1. 程式人生 > >Spring原始碼系列 — Bean生命週期

Spring原始碼系列 — Bean生命週期

前言

上篇文章中介紹了Spring容器的擴充套件點,這個是在Bean的建立過程之前執行的邏輯。承接擴充套件點之後,就是Spring容器的另一個核心:Bean的生命週期過程。這個生命週期過程大致經歷了一下的幾個階段

在本節中重點介紹例項化、填充裝配、喚醒Aware方法、BeanPostProcessor後置處理、初始化等過程。關於Bean的銷燬過程這裡不再介紹。由於Bean的生命週期的維護過程實際上都是由BeanFactory負責,所以在開始Bean的生命週期過程詳解之前,先概覽性瞭解BeanFactory。本文目錄:

  • BeanFactory概覽
  • Bean的例項化
  • Bean的裝配
  • Bean的後置處理
  • Bean的初始化

BeanFactory概覽

簡單點說,BeanFactory就是Spring框架的核心,它負責Bean的整個生命週期的管理。在Spring中對該抽象出了一套BeanFactory的介面,仍然遵守介面隔離,單一職責原則。

Spring將BeanFactory抽象出了最頂層介面,主要提供給client一個Spring容器的檢視。
下面都是根據BeanFactory的功能進行劃分拆分隔離出不同功能的Bean工廠:

  1. 具有層次的BeanFactory,存在父子關係
  2. 可羅列的BeanFactory,提供獲取Bean定義個數、獲取所有的Bean名稱、獲取所有Bean定義等等的可羅列的能力
  3. 具有裝配能力的BeanFactory,提供自動裝配Bean的能力,這個可謂是Spring的核心,自動裝配依賴注入
  4. 可配置的BeanFactory,提供配置父BeanFactory、類載入器、轉換服務等等能力

這一套BeanFactory可謂抽象的淋漓盡致。從這裡也可以看出Spring設計上的優秀程度,也提現作者們的面向物件的思維和設計模式的功底。

再者就是實現,其中AbstractBeanFactory無疑是核心,它是BeanFactory的基本能力的實現,提供了以下幾點特性:

  1. 能夠獲取BeanDefinition,所以可以被實現可羅列的BeanFactory繼承擴充套件
  2. 提供基本的單例建立的模板方法doGetBean,同時繼承了SingletonBeanRegistry的實現DefaultSingletonBeanRegistry,從而具有單例快取能力
  3. 實現了HierarchicalBeanFactory和ConfigurableBeanFactory介面,從而具有BeanFactory的層次能力,也具有配置BeanFactory的能力

AbstractAutowireCapableBeanFactory在AbstractBeanFactory的基礎上擴充套件實現AutowireCapableBeanFactory介面,從而具有裝配能力的BeanFactory。

DefaultListableBeanFactory是繼承AbstractAutowireCapableBeanFactory並且實現ListableBeanFactory介面,從而具有可羅列的功能。它也是Spring中核心實現。基本上所有的上下文都是通過持有該BeanFactory實現,從而具有管理Bean的能力。

為了更形象直觀的瞭解Bean的實現細節,先看下Bean的例項化、裝配、後置處理、初始化的時序圖:

Bean的例項化

Bean的例項化過程非常複雜,但是簡單的概括,也就一個邏輯:從BeanDefinition華麗的轉身至配置的Bean物件的過程,這節承接上篇文章擴充套件點,繼續看AbstractApplicationContext的模板方法refresh後續的例項化Bean的邏輯流程。關於Bean的屬性,如:Lazy-Init/Scope/Autowired Way等等,這裡不再介紹,讀者可以移步至Spring官網翻閱文件。

首先依然從源頭refresh的模板方法著手:

try {
    // Allows post-processing of the bean factory in context subclasses.
    postProcessBeanFactory(beanFactory);
    // Invoke factory processors registered as beans in the context.
    invokeBeanFactoryPostProcessors(beanFactory);
    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);
    
    ... 忽略

    // 模板方法中,這一步完成Bean工廠中遺留下的非惰性的Bean的例項化
    // Instantiate all remaining (non-lazy-init) singletons.
    finishBeanFactoryInitialization(beanFactory);
    // Last step: publish corresponding event.
    finishRefresh();
}catch (BeansException ex) {
    ... 忽略
}

finishBeanFactoryInitialization該方法是正式開始例項化應用配置的Bean的核心步驟(並不是所有的Bean都是這一步驟中例項化,如前篇文章中的那些擴張點,在這之前就已經例項化)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 在例項化剩餘的Bean之前,需要針對BeanFactory進行配置
    // 1. 配置BeanFactory的轉換service
    // Initialize conversion service for this context.
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }
    // 配置值解析器
    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }
    // 過早例項化LoadTimeWeaverAware
    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    // 停止使用temporary ClassLoader
    // Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);
    // 凍結配置,已經在例項化階段且經過了BeanFactoryPostProcessor,不允許修改Bean定義
    // Allow for caching all bean definition metadata, not expecting further changes.
    beanFactory.freezeConfiguration();
    // 例項化遺留的非惰性單例Bean
    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons是ConfigurableListableBeanFactory工廠介面抽象的介面,確保非惰性的單例能夠被例項化。預設實現是DefaultListableBeanFactory:

@Override
public void preInstantiateSingletons() throws BeansException {
    if (logger.isDebugEnabled()) {
        logger.debug("Pre-instantiating singletons in " + this);
    }
    // 在bean定義的拷貝上迭代,當是非規則的factory,初始化方法仍然能增加bean定義,也能正常規則
    // 非規則的factory,很少使用,這裡不做太多關注
    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    // 這裡出發非惰性的單例的例項化
    // Trigger initialization of all non-lazy singleton beans...
    // 迭代每個bean名稱,按名稱逐個例項化
    for (String beanName : beanNames) {
        // 根據bean名稱獲取其對應的RootBeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 當是非抽象,且是單例,非惰性bean,則進行初始化;否則迭代下一個bean
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 判斷該名稱的bean是否為工廠bean
            if (isFactoryBean(beanName)) {
                // 是工廠bean,則先獲取該Bean對應的FactoryBean,在Spring中FactoryBean的名稱命名規則為:"&" + "beanName"
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                boolean isEagerInit;
                // 判斷該工廠Bean是否可以過早例項化
                // 標準的FactoryBean是不過早例項化的,只有在被呼叫進行實際訪問時才例項化
                // 而SmartFactoryBean提供了可以設定是否儘早例項化
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                    isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                        @Override
                        public Boolean run() {
                            return ((SmartFactoryBean<?>) factory).isEagerInit();
                        }
                    }, getAccessControlContext());
                }
                else {
                    // 非SmartFactoryBean時,則不例項化;如果是,則判斷SmartFactoryBean的儘早例項化的設定引數
                    isEagerInit = (factory instanceof SmartFactoryBean &&
                            ((SmartFactoryBean<?>) factory).isEagerInit());
                }
                // 如果非過早例項化,則迭代下一個Bean名稱
                if (isEagerInit) {
                    getBean(beanName);
                }
            }
            // 非工廠bean
            else {
                // 獲取該Bean名稱對應的單例物件
                // getBean是BeanFactory介面定義的介面,是面向Spring內部和應用的介面
                // 其中包含了Bean的生命週期的部分
                // getBean非常重要,是觸發Bean的入口,也是獲取Bean工廠中已存在單例的手段
                getBean(beanName);
            }
        }
    }
    // Trigger post-initialization callback for all applicable beans...
    // 針對所有Bean觸發後置例項化回撥,這裡忽略
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

以上就是例項化Bean的觸發點,邏輯也是非常直觀,只要滿足非惰性單例的Bean才能進行例項化。其中分為兩種情形:

  • 工廠Bean,對於工廠Bean判斷是否為SmartFactoryBean,決定是否可以儘早例項化
  • 非工廠Bean

由於篇幅原因,關於isFactoryBean的實現這裡不再詳細介紹,可以自行閱讀。接下來再繼續看getBean的實現。getBean是AbstractBeanFactory中的基礎實現:

@Override
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

其中內部呼叫doGetBean方法,方法引數較多:

  1. 第一個引數是Bean名稱
  2. 第二個引數是被要求的型別
  3. 第三個引數是建立單例時需要使用的構造引數
  4. 第三個參標誌是否為只僅僅型別檢查獲取,而非實際使用

doGetBean是AbstractBeanFactory中實現獲取Bean的模板方法,作為BeanFactory的基礎實現類,子類可以擴充套件實現建立Bean的邏輯。其中實現以下模板步驟:

  1. 從單例快取中獲取Bean
  2. 從父BeanFactory中獲取該Bean
  3. 先獲取該Bean的依賴Bean
  4. 按照不同的Bean作用域建立該Bean,該步驟被抽象為抽象介面,由子類實現擴充套件
  5. 如果該Bean是工廠Bean,則呼叫工廠Bean的生產方法getObject生成新的Bean
  6. 檢查型別是否匹配,如果不匹配,則進行型別轉換
protected <T> T doGetBean(
        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
        throws BeansException {
    // 組裝bean名稱
    final String beanName = transformedBeanName(name);
    Object bean;
    // 檢查快取,檢查是否已經過早例項化了該bean
    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    // 如果不為空,則表示已經過早的例項化了該bean
    if (sharedInstance != null && args == null) {
        // 日誌列印
        if (logger.isDebugEnabled()) {
            // Spring中使用singletonsCurrentlyInCreation Set集合來儲存正在建立的單例Bean的名稱
            // 如果其中包含該beanName,則表示是迴圈引用
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        // 如果該bean是工廠bean,則返回生產後的bean
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    // 如果沒有過早的例項化
    else {
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
        //  檢查是否有父BeanFactory
        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 如果父BeanFactory不為空,則該Bean的Bean定義被包含在BeanFactory中
        // 則使用父BeanFactory獲取該Bean,並返回建立的Bean
        // 這裡實現了層次BeanFactory的能力,有點類似Java中的類載入器委託機制
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }
        // 如果父BeanFactory為空且非只僅僅型別檢查,則標記該Bean正在被建立
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }
        try {
            // 獲取該Bean對應的RootBeanDefinition
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
            // Guarantee initialization of beans that the current bean depends on.
            // 獲取該Bean依賴的Bean名稱
            String[] dependsOn = mbd.getDependsOn();
            // 遍歷獲取依賴的Bean
            // 例項化該bean前,先例項化其依賴的Bean
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }
            // 再根據不同的作用域建立該Bean
            // Create bean instance.
            // 這裡只重點看單例Bean的建立過程,對於其他作用域型別,讀者自行閱讀
            // 這裡就是模板方法的擴充套件點,createBean是定義的抽象介面,由子類擴充套件實現建立Bean的過程
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    @Override
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }
            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                            "Scope '" + scopeName + "' is not active for the current thread; consider " +
                            "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }
    // 建立完Bean後,做型別檢查,是否與要求的型別匹配,如果不匹配,則進行型別轉換並返回
    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
        try {
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        }
        catch (TypeMismatchException ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Failed to convert bean '" + name + "' to required type '" +
                        ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

這裡有三點需要注意:

  • getSingleton,從單例快取中獲取該Bean,因為由於迴圈關係可能會導致過早初始化該Bean
  • markBeanAsCreated,防止Bean重複建立,當Bean準備開始建立錢,需要記錄
  • getMergedLocalBeanDefinition,任何Bean都有可能存在父Bean,所以需要獲取合併的Bean定義,在Spring中建立Bean時,都會將Bean定義轉為RootBeanDefinition進行統一處理

createBean是子類的擴充套件實現Bean的建立過程,在Spring中預設由AbstractAutowireCapableBeanFactory中實現了Bean的實際建立:

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;
    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    // 解析該Bean的Class型別
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    // 如果該Bean沒有BeanClass,則設定。這裡深度複製,不修改原有的Bean定義
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }
    // Prepare method overrides.
    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }
    try {
        // 給BeanPostProcessors返回目標Bean的代理物件
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        // 如果代理物件存在,則返回
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }
    // 如果沒有代理物件,則這裡建立該Bean
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isDebugEnabled()) {
        logger.debug("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
}

這裡主要邏輯是:在例項化Bean錢確保解析Bean Class,在例項化之前增加擴充套件點,最後呼叫實際的建立Bean的邏輯。

關於例項化之前的擴張點,這裡不再詳述,後續再介紹AOP的篇幅中再詳述描述。讀者也可以自行閱讀InstantiationAwareBeanPostProcessor的抽象。

接下來再繼續閱讀建立Bean的細節doCreateBean:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
        throws BeanCreationException {
    // Instantiate the bean.
    // 例項化的Bean的包裝器
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // 如果例項化的Bean的包裝器是空,則建立Bean
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 獲取例項化的Bean
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    mbd.resolvedTargetType = beanType;
    // 後置處理修改合併的RootBeanDefinition,筆者也沒遇到過這種情形,這裡忽略
    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }
    // 儘早快取該Bean,以便後續迴圈引用時可以正常解析(迴圈引用時,直接從快取中獲取即可,不會再重新建立Bean)
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }
    
    ... 省略部分是Bean裝配和初始化的邏輯

    // 返回建立的Bean
    return exposedObject;
}

這裡需要重點關注的是儘早快取該Bean例項,主要是為了解決迴圈引用的問題。在下節Bean的裝配中,再回到這裡重點介紹。

前文中介紹到CreateBean是由子類擴充套件實現相應的例項化Bean的邏輯,在Spring中,這裡使用回撥的方式,再回到回撥的點細看getSingleton方法的實現:

// 該方法是由單例註冊器DefaultSingletonBeanRegistry實現,它具有快取單例的能力
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "'beanName' must not be null");
    // 同步singletonObjects,保證執行緒安全,資料一致
    // singletonObjects儲存Spring容器中的所有單例Bean
    synchronized (this.singletonObjects) {
        // 首先從單例容器中獲取該單例
        Object singletonObject = this.singletonObjects.get(beanName);
        // 如果單例不存在,則建立該單例Bean
        if (singletonObject == null) {
            // 判斷該單例是否正在銷燬中,如果正在銷燬,則丟擲異常
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName,
                        "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                        "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            // 這裡是一個擴充套件點,用於在創鍵單例錢進行回撥
            // 預設實現中是判斷該單例是否正在建立,防重建立,其中使用Set保證唯一
            beforeSingletonCreation(beanName);
            // 創鍵是否為新的單例標誌
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<Exception>();
            }
            // 這裡回撥物件工廠建立單例,呼叫將回到CreateBean那裡
            // 並更新為新的單例的表示
            try {
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // Has the singleton object implicitly appeared in the meantime ->
                // if yes, proceed with it since the exception indicates that state.
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw ex;
                }
            }
            catch (BeanCreationException ex) {
                if (recordSuppressedExceptions) {
                    for (Exception suppressedException : this.suppressedExceptions) {
                        ex.addRelatedCause(suppressedException);
                    }
                }
                throw ex;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                // 建立單例的後置回撥
                afterSingletonCreation(beanName);
            }
            // 將新的單例存入單例容器中
            if (newSingleton) {
                addSingleton(beanName, singletonObject);
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }
}

比較這裡的單例容器和之前提到的儘早快取單例的容器:

1.建立單例完成,將單例存入單例容器中

protected void addSingleton(String beanName, Object singletonObject) {
    // 同步單例容器singletonObjects
    synchronized (this.singletonObjects) {
        // 存入單例,使用對映表 beanName -> singletonObject
        this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
        // 單例已經建立完成,則清理之前的儘早快取的單例工廠物件
        this.singletonFactories.remove(beanName);
        // 清理過早快取的該單例物件
        this.earlySingletonObjects.remove(beanName);
        // 在已經註冊的單例中,註冊上該單例名稱,表示該單例已經註冊
        this.registeredSingletons.add(beanName);
    }
}

2.過早快取單例,解決迴圈引用

// 如果是單例,且Spring容器允許迴圈引用,該bean當前正在被建立
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
// 如果允許過早暴露單例
if (earlySingletonExposure) {
    if (logger.isDebugEnabled()) {
        logger.debug("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
    }
    // 將單例的物件工廠快取
    addSingletonFactory(beanName, new ObjectFactory<Object>() {
        @Override
        public Object getObject() throws BeansException {
            return getEarlyBeanReference(beanName, mbd, bean);
        }
    });
}


protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    // 同步singletonObjects
    synchronized (this.singletonObjects) {
        // 如果singletonObjects中不包含該單例,則過早快取
        if (!this.singletonObjects.containsKey(beanName)) {
            // 快取建立這個bean物件的工廠
            this.singletonFactories.put(beanName, singletonFactory);
            // 從過早快取容器中移除該bean,下次過早引用該bean時,重新從上面快取的工廠中重新獲取
            this.earlySingletonObjects.remove(beanName);
            // 將該bean註冊到單例中
            this.registeredSingletons.add(beanName);
        }
    }
}

// 過早獲取該bean的單例,這裡主要是為了解決迴圈引用問題
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 首先從singletonObjects中獲取,如果有直接返回
    Object singletonObject = this.singletonObjects.get(beanName);
    // 如果不存在,且正在建立中
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        // 同步singletonObjects
        synchronized (this.singletonObjects) {
            // 從過早快取的容器中獲取
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 如果過早快取的容器中也沒有且支援過早引用
            if (singletonObject == null && allowEarlyReference) {
                // 獲取上述中提到的過早快取的工廠
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                // 快取工廠不為空
                if (singletonFactory != null) {
                    // 獲取該物件,將會呼叫getEarlyBeanReference方法
                    singletonObject = singletonFactory.getObject();
                    // 將其快取到過早快取中,避免下次再使用工廠獲取
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 將該工廠存快取中移除
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    // 返回該物件
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

Spring處理迴圈引用的方式非常巧妙,為了幫助理解,筆者這裡整理了下流程圖幫助理解:

到這裡Bean的創鍵基本上完成,後續就是依賴注入,將Bean裝配起來。

Bean的裝配

什麼是Bean的裝配,即自動解決Bean之間的相互引用,能夠將其各自Set進彼此之中。比如,BeanA引用了BeanB,則Spring能自動的將連個Bean都例項化,然後將BeanB Set至BeanA中,這就是依賴注入,自動裝配。

Bean的裝配發生在Bean的例項化之後,在Spring中由AbstractAutowireCapableBeanFactoryBean工廠完成。繼續閱讀原始碼:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
            throws BeanCreationException {
        ...省略,這部分是例項化邏輯,上節中已經詳解
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            // 這裡處理Bean的裝配
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                這裡處理Bean的初始化
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }
        ... 省略
        return exposedObject;
    }

Bean的裝配由populateBean中實現:

// 該實現中處理Spring中的Bean裝配
// 有按照名稱、按照型別兩種正規化裝配
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    // 獲取Bean定義的屬性值,Bean定義的屬性值代表著需要裝配的成員域
    PropertyValues pvs = mbd.getPropertyValues();
    // 如果是空例項,則跳過返回,不裝配
    if (bw == null) {
        if (!pvs.isEmpty()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            // Skip property population phase for null instance.
            return;
        }
    }
    // 這裡是一個擴充套件點,用於例項化後的後置處理InstantiationAwareBeanPostProcessor
    // InstantiationAwareBeanPostProcessor是BeanPostProcessor的擴充套件實現,前文中也稍微提過
    // 對於後置處理返回false,表示不需要裝配,否則需要裝配
    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    boolean continueWithPropertyPopulation = true;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }
    // 如果不需要按照屬性裝配,則直接返回
    if (!continueWithPropertyPopulation) {
        return;
    }
    // 獲取Bean定義中的裝配模式
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        // 重新copy一份屬性值
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // 按照名稱進行屬性裝配
        // Add property values based on autowire by name if applicable.
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // 按照型別進行屬性裝配
        // Add property values based on autowire by type if applicable.
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

    // 同樣是InstantiationAwareBeanPostProcessor後置處理屬性值的擴充套件點
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
    if (hasInstAwareBpps || needsDepCheck) {
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
        if (needsDepCheck) {
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }
    // 應用屬性值到Bean中
    applyPropertyValues(beanName, mbd, bw, pvs);
}

其中非常重要的三個邏輯是:

  1. 按照名稱進行屬性裝配
  2. 按照型別進行屬性裝配
  3. 應用屬性值到Bean中

其次是InstantiationAwareBeanPostProcessor擴充套件點,它提供了例項化前後的擴充套件。
例項化前可以擴充套件實現自定義的例項化Bean邏輯;例項化後擴充套件可以實現自定義的裝配方式。同時也提供了後置處理即將被工廠應用到Bean的屬性值的擴充套件點。這裡由於篇幅不再詳述,同樣在後續AOP章節中講解。

這裡圍繞按照型別進行屬性裝配和應用屬性值到Bean中做詳細講解。其中關於如何配置裝配方式,這裡不再贅述,可以翻閱文件。

Notes:
需要注意以上的實現中由重新複製MutablePropertyValues的操作,因為在按名稱和按型別進行裝配的過程中,會修改Bean定義的屬性,故這裡將其沖洗copy一份用於修改:將裝配的值解析後,覆蓋寫入Bean定義屬性中。

// 完成按照型別裝配Bean
// 第一個引數是Bean名稱、第二個引數是該Bean對應的Bean定義,第三個引數是該bean的包裝物件,第四個引數是該Bean的屬性值描述
protected void autowireByType(
        String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    // 獲取BeanFactory中配置的自定義型別轉換器,如果未配置,則使用BeanWrapper
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    // 指定大小,建立需要自動裝配的Bean名稱
    Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
    // 從Bean的屬性描述pvs中篩選出非簡單的滿足裝配的屬性名稱
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    // 遍歷需要裝配的屬性名稱
    for (String propertyName : propertyNames) {
        try {
            // 這裡使用javabeans技術,獲取屬性描述器
            PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
            // 如果裝配的型別是Object型別,則沒有任何意義,無法裝配,直接迭代下一個
            // Don't try autowiring by type for type Object: never makes sense,
            // even if it technically is a unsatisfied, non-simple property.
            // 非Object型別
            if (Object.class != pd.getPropertyType()) {
                // 獲取該成員屬性的方法引數
                MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                // Do not allow eager init for type matching in case of a prioritized post-processor.
                boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
                DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                // 這裡解析該屬性成員,這裡會從BeanFactory中尋找該屬性的候選者,找到後,再進行例項化。返回屬性對應的Bean
                // 如A -> B,正在解析B,則這裡將返回B
                Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                // 將屬性和候選者新增到屬性值中
                if (autowiredArgument != null) {
                    pvs.add(propertyName, autowiredArgument);
                }
                // 註冊依賴關係,正向依賴和反向依賴
                for (String autowiredBeanName : autowiredBeanNames) {
                    registerDependentBean(autowiredBeanName, beanName);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
                                propertyName + "' to bean named '" + autowiredBeanName + "'");
                    }
                }
                // 清理autowiredBeanNames,繼續下一個迭代
                autowiredBeanNames.clear();
            }
        }
        catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
        }
    }
}

這裡的邏輯和後續解析依賴的邏輯比較複雜,這裡通過舉例幫助理解。

假如:Bean A持有成員域B。配置如下:

public class A {

    private B b;
}


<bean id="a" class=".....A" autowire="byType">
</bean>

<bean id="b" class=".....B" autowire-candidate="true">
</bean>

A自動裝配方式按照型別裝配,當a例項化後,在裝配時,需要對b成員進行填充。那麼unsatisfiedNonSimpleProperties方法返回的屬性陣列中將會包含"b"。

// 獲取Bean的不滿足非簡單的屬性
// 這裡主要使用的是javabeans的自省技術,如果對這裡感興趣可以參考oracle java中的javabeans技術
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
    // 
    Set<String> result = new TreeSet<String>();
    // 獲取bean定義中的屬性值
    PropertyValues pvs = mbd.getPropertyValues();
    // 獲取該Bean例項中所有屬性描述器
    PropertyDescriptor[] pds = bw.getPropertyDescriptors();
    // 遍歷屬性描述器
    for (PropertyDescriptor pd : pds) {
        // 屬性描述器有寫方法,且該屬性沒有被排除依賴,且bean定義的屬性中不包含該屬性,且非簡單屬性,則認為需要自動裝配
        if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
            result.add(pd.getName());
        }
    }
    return StringUtils.toStringArray(result);
}

以上的b屬性是滿足,首先通過PropertyDescriptor[] pds = bw.getPropertyDescriptors()能獲取到屬性b的描述,然後b又未被排除依賴,在a的bean定義配置中也未配置b,且b是非簡單屬性。在Spring中認為這些屬性是簡單屬性:

public static boolean isSimpleValueType(Class<?> clazz) {
    return (ClassUtils.isPrimitiveOrWrapper(clazz) ||
            Enum.class.isAssignableFrom(clazz) ||
            CharSequence.class.isAssignableFrom(clazz) ||
            Number.class.isAssignableFrom(clazz) ||
            Date.class.isAssignableFrom(clazz) ||
            URI.class == clazz || URL.class == clazz ||
            Locale.class == clazz || Class.class == clazz);
}

且如果是以上這些型別的元素陣列型別,也被認為是簡單型別。故b是需要被自動裝配。

後續便是從BeanFactory的Bean定義中尋找b的候選者:

@Override
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
        Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    // 以下javaxInjectProviderClass、javaUtilOptionalClass、ObjectFactory、ObjectProvider這些都是特殊型別
    // 這裡不做講解
    descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
    if (javaUtilOptionalClass == descriptor.getDependencyType()) {
        return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
    }
    else if (ObjectFactory.class == descriptor.getDependencyType() ||
            ObjectProvider.class == descriptor.getDependencyType()) {
        return new DependencyObjectProvider(descriptor, requestingBeanName);
    }
    else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
        return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
    }
    else {
        // 應用配置的Bean大多數進入該分支
        // 對實際依賴的惰性物件構造一個代理作為需要被裝配成員例項
        Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                descriptor, requestingBeanName);
        // 如果為空,則解析依賴
        if (result == null) {
            result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
        }
        return result;
    }
}

顯然解析a對b的依賴,會進入最後一條分支,descriptor是b的屬性描述器,requestingBeanName是a,autowiredBeanNames是包含"b",型別轉換器是a例項的Bean包裝器。

// 這裡邏輯非常複雜,只重點關注核心邏輯
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
        Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    try {
        Object shortcut = descriptor.resolveShortcut(this);
        if (shortcut != null) {
            return shortcut;
        }
        // 根據屬性描述器獲取依賴物件的型別
        Class<?> type = descriptor.getDependencyType();
        Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
        if (value != null) {
            if (value instanceof String) {
                String strVal = resolveEmbeddedValue((String) value);
                BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
                value = evaluateBeanDefinitionString(strVal, bd);
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            return (descriptor.getField() != null ?
                    converter.convertIfNecessary(value, type, descriptor.getField()) :
                    converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
        }
        Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
        if (multipleBeans != null) {
            return multipleBeans;
        }
        // 按照型別尋找bean候選者的bean名稱
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
        if (matchingBeans.isEmpty()) {
            if (isRequired(descriptor)) {
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            return null;
        }

        // 決定候選者中的一個成為被裝配的Bean
        String autowiredBeanName;
        Object instanceCandidate;
        if (matchingBeans.size() > 1) {
            autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
            if (autowiredBeanName == null) {
                if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                    return descriptor.resolveNotUnique(type, matchingBeans);
                }
                else {
                    // In case of an optional Collection/Map, silently ignore a non-unique case:
                    // possibly it was meant to be an empty collection of multiple regular beans
                    // (before 4.3 in particular when we didn't even look for collection beans).
                    return null;
                }
            }
            instanceCandidate = matchingBeans.get(autowiredBeanName);
        }
        else {
            // We have exactly one match.
            Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
            autowiredBeanName = entry.getKey();
            instanceCandidate = entry.getValue();
        }
        if (autowiredBeanNames != null) {
            autowiredBeanNames.add(autowiredBeanName);
        }
        // 例項化被裝配的Bean並返回
        return (instanceCandidate instanceof Class ?
                descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
    }
    finally {
        ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    }
}

當按照型別B從BeanFactory中尋找後選擇時,會尋找到"b"的bean名稱,後續在例項化時,將例項化b配置的Bean。

其中descriptor.resolveCandidate例項化需要重點關注:

// 是不是很熟悉,又是呼叫BeanFactory的getBean,這是BeanFactory的基本能力
// 當解析依賴的時候,這裡是間接遞迴呼叫
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
        throws BeansException {
    return beanFactory.getBean(beanName, requiredType);
}

當解析依賴的時候,將會間接遞迴呼叫getBean方法。這裡將會getBean("b", .....B)。

當解析到被裝配的Bean後,就會加入至屬性對映pvs中。最後再呼叫applyPropertyValues將屬性填入。這裡即將b填充至a中。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    // 如果沒有屬性,則直接返回,無可應用
    if (pvs == null || pvs.isEmpty()) {
        return;
    }
    if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
        ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
    }
    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;
    // 如果MutablePropertyValues是已經被轉換,則直接短路填充
    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        if (mpvs.isConverted()) {
            // Shortcut: use the pre-converted values as-is.
            try {
                bw.setPropertyValues(mpvs);
                return;
            }
            catch (BeansException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Error setting property values", ex);
            }
        }
        original = mpvs.getPropertyValueList();
    }
    else {
        original = Arrays.asList(pvs.getPropertyValues());
    }
    // 否則獲取自定義轉換器
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    // 構建Bean定義值解析器
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
    // Create a deep copy, resolving any references for values.
    List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
    boolean resolveNecessary = false;
    // 遍歷屬性值
    for (PropertyValue pv : original) {
        // 如果屬性值已經被轉換,直接加入到列表中
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        else {
            // 獲取屬性名,屬性值
            String propertyName = pv.getName();
            Object originalValue = pv.getValue();
            // 解析屬性值
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            boolean convertible = bw.isWritableProperty(propertyName) &&
                    !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            // 避免重新裝換,存入到合併的bean定義中
            // Possibly store converted value in merged bean definition,
            // in order to avoid re-conversion for every created bean instance.
            if (resolvedValue == originalValue) {
                if (convertible) {
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            else if (convertible && originalValue instanceof TypedStringValue &&
                    !((TypedStringValue) originalValue).isDynamic() &&
                    !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            }
            else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }
    if (mpvs != null && !resolveNecessary) {
        mpvs.setConverted();
    }
    // 填充屬性值
    // Set our (possibly massaged) deep copy.
    try {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}

這裡需要關注的是resolveValueIfNecessary方法。當未按照型別和名稱進行自動裝配時,BeanDefinitionValueResolver幫助類將會解析被包含在Bean定義中的值為實際的Bean並且將其填充到目標Bean例項中,

上述的Notes中提到有MutablePropertyValues重新copy,然後將解析的依賴值覆蓋寫入到屬性中,這裡resolveValueIfNecessary中將會抉擇Bean定義屬性值的型別,如果是實際待裝配填充的值,則不做任何處理;否則將會根據Bean定義屬性的值型別,做相應處理,具體細節這裡不再贅述。

Bean的後置處理

在Bean裝配完畢後,這個Bean就已經初具形態,基本上是一個完整的Bean。因為物件就是成員與行為的集合,裝配即補齊其依賴的成員。這是便可以執行Bean的初始化了,但是Spring提供了擴充套件點,在初始化前後都為應用預留了擴張點。

上篇文章中介紹到BeanPostProcessor的容器擴充套件點,只是講解了Spring上下文如何例項化和註冊BeanPostProcessor,單對於BeanPostProcessor的喚醒呼叫沒有提及,這裡有了Bean建立的基礎,再來看該問題。

繼續原始碼分析,在裝配完成後,開始初始化:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    // 由於部分物件可能會有訪問安全控制,所以需要做許可權訪問
    // 在初始化和後置處理前,需要處理Spring中的另一個擴充套件點Aware介面
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                // 帶有許可權控制,喚醒Aware介面,注入相應的Bean
                invokeAwareMethods(beanName, bean);
                return null;
            }
        }, getAccessControlContext());
    }
    else {
        // 喚醒Aware介面,注入相應的Bean
        invokeAwareMethods(beanName, bean);
    }
    // 初始化前的後置處理,喚醒BeanPostProcessor的applyBeanPostProcessorsBeforeInitialization
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    try {
        // 喚醒初始化方法,初始化Bean
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }
    // 初始化完成後的後置處理,喚醒BeanPostProcessor的applyBeanPostProcessorsAfterInitialization
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

這裡重點看前後的後置處理,至於Aware介面的處理和初始化的執行,下節再詳細分析。

1.初始化前的後置處理

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {
    // 遍歷呼叫BeanFactory中的BeanPostProcessor,然後後置處理該Bean
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        result = processor.postProcessBeforeInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    // 返回結果
    return result;
}

2.初始化後的後置處理

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {
    // 遍歷呼叫BeanFactory中的BeanPostProcessor後置處理初始化後的Bean
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        result = processor.postProcessAfterInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    // 返回處理後的結果
    return result;
}

Bean的初始化

上節Bean的後置處理中已經初步提及到初始化的過程:

  1. 處理Spring的Aware系列介面
  2. 初始化前的後置處理
  3. 喚醒Bean的初始化
  4. 初始化後的後置處理

1.處理Aware介面

private void invokeAwareMethods(final String beanName, final Object bean) {
    // 首先如果該Bean是Aware例項
    if (bean instanceof Aware) {
        // 如果該bean是BeanNameAware例項
        if (bean instanceof BeanNameAware) {
            // 則將該Beand的beanName set進該Bean中
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        // 如果該Bean是BeanClassLoaderAware例項
        if (bean instanceof BeanClassLoaderAware) {
            // 則將載入該Bean的類載入器set進該beanzhong 
            ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
        }
        // 如果該Bean是BeanFactoryAware的例項
        if (bean instanceof BeanFactoryAware) {
            // 則將BeanFactory set進該Bean中
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

這裡只處理BeanNameAware、BeanClassLoaderAware和BeanFactoryAware三個Aware介面。但是在Spring中還有很多Aware介面,如:

  • 經常使用的ApplicationContextAware介面
  • ResourceLoaderAware介面
  • MessageSourceAware介面
  • EnvironmentAware介面

等等,它們是在何處處理的?Spring中針對這些介面使用了BeanPostProcessor的方式注入相應的Bean。

以上的這些Aware介面要求注入分別是ApplicationContext,ResourceLoader,MessageSource,Environment。

但是這些都是更偏上層應用,BeanFactory屬於更底層的基礎元件,所以不可能依賴倒轉,在BeanFactory中處理這些Aware介面,將處理這些Aware介面的依賴注入。這樣勢必會造成BeanFactory依賴反轉,與上層的這些介面耦合,那樣違背設計。

同時需要注意到的是,ApplicationContext,ResourceLoader,MessageSource,Environment這些元件都是可以通過ApplicationContext一致對外提供介面,所以只要向實現這些介面的Bean中注入ApplicationContext即可。

Spring中使用ApplicationContextAwareProcessor的BeanPostProcessor後置處理,完成ApplicationContext注入到實現以上介面的Bean中:

@Override
public Object postProcessBeforeInitialization(final Object bean,