死磕Spring之IoC篇 - Bean 的建立過程

該系列文章是本人在學習 Spring 的過程當中總結下來的,裏面涉及到相關源碼,可能對讀者不太友好,請結合個人源碼註釋 Spring 源碼分析 GitHub 地址 進行閱讀html

Spring 版本:5.1.14.RELEASEjava

開始閱讀這一系列文章以前,建議先查看《深刻了解 Spring IoC(面試題)》這一篇文章git

該系列其餘文章請查看:《死磕 Spring 之 IoC 篇 - 文章導讀》github

Bean 的建立過程

上一篇《開啓 Bean 的加載》文章分析了 Bean 的整個加載過程,當咱們顯示或者隱式地調用AbstractBeanFactorygetBean(...) 方法時,會觸發 Bean 的加載,會進行一系列的處理,具體實現可查看上一篇文章。面試

對於不一樣做用域的 Bean,底層都會調用 AbstractAutowireCapableBeanFactorycreateBean(...) 方法進行建立,建立 Bean 的過程涉及到 Bean 生命週期的大部分階段,例如實例化階段、屬性賦值階段、Aware 接口回調階段、初始化階段都是在這個方法中完成的,這個核心方法在上一篇文章沒有講述,接下來將在本文進行分析。spring

AbstractAutowireCapableBeanFactory

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 抽象類,繼承 AbstractBeanFactory,實現 AutowireCapableBeanFactory 接口,完成 Bean 的建立express

【核心】createBean 方法

createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 方法,建立 Bean,方法以下:緩存

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    if (logger.isTraceEnabled()) {
        logger.trace("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.
    // <1> 獲取 `mbd` 對應的 Class 對象,確保當前 Bean 可以被建立出來
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    // 若是這裏獲取到了 Class 對象,可是 `mbd` 中沒有 Class 對象的相關信息,表示這個 Class 對象是動態解析出來的
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        // 複製一份 `mbd`,並設置 Class 對象,由於動態解析出來的 Class 對象不被共享
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        // <2> 對全部的 MethodOverride 進行驗證和準備工做(確保存在對應的方法,並設置爲不能重複加載)
        mbdToUse.prepareMethodOverrides();
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        /**
         * <3> 在實例化前進行相關處理,會先調用全部 {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}
         * 注意,若是這裏返回對象不是 `null` 的話,不會繼續往下執行本來初始化操做,直接返回,也就是說這個方法返回的是最終實例對象
         * 能夠經過這種方式提早返回一個代理對象,例如 AOP 的實現,或者 RPC 遠程調用的實現(由於本地類沒有遠程能力,能夠經過這種方式進行攔截)
         */
        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);
    }

    try {
        // <4> 建立 Bean 對象 `beanInstance`,若是上一步沒有返回代理對象,就只能走常規的路線進行 Bean 的建立了
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        // <5> 將 `beanInstance` 返回
        return beanInstance;
    } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        // A previously detected exception with proper bean creation context already,
        // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
        throw ex;
    } catch (Throwable ex) {
        throw new BeanCreationException(
                mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

入參:安全

  • beanName:Bean 的名稱
  • mbd:Bean 的 BeanDefinition 對象(合併後)
  • args:建立 Bean 的參數,咱們一般不會傳,因此這裏爲 null

過程大體以下:app

  1. 獲取 mbd 對應的 Class 對象,確保當前 Bean 可以被建立出來,調用 resolveBeanClass(...) 方法

  2. 對全部的 MethodOverride 進行驗證準備工做(確保存在對應的方法,並設置爲不能重複加載)

  3. 實例化前階段在實例化前進行相關處理,會先調用全部 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

    注意,若是這裏返回對象不是 null 的話,不會繼續往下執行本來初始化操做,直接返回,也就是說這個方法返回的是最終實例對象

    能夠經過這種方式提早返回一個代理對象,例如 AOP 的實現,或者 RPC 遠程調用的實現(由於本地類沒有遠程能力,能夠經過這種方式進行攔截)

  4. 建立 Bean 對象 beanInstance,若是上一步沒有返回代理對象,就只能走常規的路線進行 Bean 的建立了,調用 doCreateBean(...) 方法

  5. beanInstance 返回

能夠看到這個方法中並無開始真正 Bean 的建立,在這個方法的第 4 步會調用 doCreateBean(...) 方法建立 Bean

【核心】doCreateBean 方法

doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args),建立 Bean,方法以下:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {

    // Instantiate the bean.
    /**
     * <1> Bean 的實例化階段,會將 Bean 的實例對象封裝成 {@link BeanWrapperImpl} 包裝對象
     * BeanWrapperImpl 承擔的角色:
     * 1. Bean 實例的包裝
     * 2. {@link org.springframework.beans.PropertyAccessor} 屬性編輯器
     * 3. {@link org.springframework.beans.PropertyEditorRegistry} 屬性編輯器註冊表
     * 4. {@link org.springframework.core.convert.ConversionService} 類型轉換器(Spring 3+,替換了以前的 TypeConverter)
     */
    BeanWrapper instanceWrapper = null;
    // <1.1> 若是是單例模式,則先嚐試從 `factoryBeanInstanceCache` 緩存中獲取實例對象,並從緩存中移除
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // <1.2> 使用合適的實例化策略來建立 Bean 的實例:工廠方法、構造函數自動注入、簡單初始化
    // 主要是將 BeanDefinition 轉換爲 BeanWrapper 對象
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // <1.3> 獲取包裝的實例對象 `bean`
    final Object bean = instanceWrapper.getWrappedInstance();
    // <1.4> 獲取包裝的實例對象的類型 `beanType`
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    // <2> 對 RootBeanDefinition(合併後)進行加工處理
    synchronized (mbd.postProcessingLock) { // 加鎖,線程安全
        // <2.1> 若是該 RootBeanDefinition 沒有處理過,則進行下面的處理
        if (!mbd.postProcessed) {
            try {
                /**
                 * <2.2> 對 RootBeanDefinition(合併後)進行加工處理
                 * 調用全部 {@link MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition}
                 * 【重要】例若有下面兩個處理器:
                 * 1. AutowiredAnnotationBeanPostProcessor 會先解析出 @Autowired 和 @Value 註解標註的屬性的注入元信息,後續進行依賴注入;
                 * 2. CommonAnnotationBeanPostProcessor 會先解析出 @Resource 註解標註的屬性的注入元信息,後續進行依賴注入,
                 * 它也會找到 @PostConstruct 和 @PreDestroy 註解標註的方法,並構建一個 LifecycleMetadata 對象,用於後續生命週期中的初始化和銷燬
                 */
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            // <2.3> 設置該 RootBeanDefinition 被處理過,避免重複處理
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    // <3> 提早暴露這個 `bean`,若是能夠的話,目的是解決單例模式 Bean 的循環依賴注入
    // <3.1> 判斷是否能夠提早暴露
    boolean earlySingletonExposure = (mbd.isSingleton() // 單例模式
            && this.allowCircularReferences // 容許循環依賴,默認爲 true
            && isSingletonCurrentlyInCreation(beanName)); // 當前單例 bean 正在被建立,在前面已經標記過
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        /**
         * <3.2>
         * 建立一個 ObjectFactory 實現類,用於返回當前正在被建立的 `bean`,提早暴露,保存在 `singletonFactories` (**三級 Map**)緩存中
         *
         * 能夠回到前面的 {@link AbstractBeanFactory#doGetBean#getSingleton(String)} 方法
         * 加載 Bean 的過程會先從緩存中獲取單例 Bean,能夠避免單例模式 Bean 循環依賴注入的問題
         */
        addSingletonFactory(beanName,
                // ObjectFactory 實現類
                () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    // 開始初始化 `bean`
    Object exposedObject = bean;
    try {
        // <4> 對 `bean` 進行屬性填充,注入對應的屬性值
        populateBean(beanName, mbd, instanceWrapper);
        // <5> 初始化這個 `exposedObject`,調用其初始化方法
        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);
        }
    }

    // <6> 循環依賴注入的檢查
    if (earlySingletonExposure) {
        // <6.1> 獲取當前正在建立的 `beanName` 被依賴注入的早期引用
        // 注意,這裏有一個入參是 `false`,不會調用上面第 `3` 步的 ObjectFactory 實現類
        // 也就是說當前 `bean` 若是出現循環依賴注入,這裏才能獲取到提早暴露的引用
        Object earlySingletonReference = getSingleton(beanName, false);
        // <6.2> 若是出現了循環依賴注入,則進行接下來的檢查工做
        if (earlySingletonReference != null) {
            // <6.2.1> 若是 `exposedObject` 沒有在初始化階段中被改變,也就是沒有被加強
            // 則使用提早暴露的那個引用
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            // <6.2.2> 不然,`exposedObject` 已經不是被別的 Bean 依賴注入的那個 Bean
            else if (!this.allowRawInjectionDespiteWrapping // 是否容許注入未加工的 Bean,默認爲 false,這裏取非就爲 true
                    && hasDependentBean(beanName)) { // 存在依賴 `beanName` 的 Bean(經過 `depends-on` 配置)
                // 獲取依賴當前 `beanName` 的 Bean 們的名稱(經過 `depends-on` 配置)
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                // 接下來進行判斷,若是依賴 `beanName` 的 Bean 已經建立
                // 說明當前 `beanName` 被注入了,而這裏最終的 `bean` 被包裝過,不是以前被注入的
                // 則拋出異常
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                            "Bean with name '" + beanName + "' has been injected into other beans [" +
                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                            "] in its raw version as part of a circular reference, but has eventually been " +
                            "wrapped. This means that said other beans do not use the final version of the " +
                            "bean. This is often the result of over-eager type matching - consider using " +
                            "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        /**
         * <7> 爲當前 `bean` 註冊 DisposableBeanAdapter(若是須要的話),用於 Bean 生命週期中的銷燬階段
         * 能夠看到 {@link DefaultSingletonBeanRegistry#destroySingletons()} 方法
         */
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    // <8> 返回建立好的 `exposedObject` 對象
    return exposedObject;
}

這個方法的處理過程有點長,以下:

  1. Bean 的實例化階段,會將 Bean 的實例對象封裝成 BeanWrapperImpl 包裝對象

    1. 若是是單例模式,則先嚐試從 factoryBeanInstanceCache 緩存中獲取實例對象,並從緩存中移除

    2. 使用合適的實例化策略來建立 Bean 的實例:工廠方法、構造函數自動注入、簡單初始化,主要是將 BeanDefinition 轉換爲 BeanWrapper 對象

      調用 createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 方法

    3. 獲取包裝的實例對象 bean

    4. 獲取包裝的實例對象的類型 beanType

  2. 對 RootBeanDefinition(合併後)進行加工處理

    1. 若是該 RootBeanDefinition 沒有處理過,則進行下面的處理
    2. 調用全部的 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition,這個過程很是重要,例如 Spring 內有下面兩個處理器:
      • AutowiredAnnotationBeanPostProcessor,會先解析出 @Autowired@Value 註解標註的屬性的注入元信息,後續進行依賴注入
      • CommonAnnotationBeanPostProcessor,會先解析出 @Resource 註解標註的屬性的注入元信息,後續進行依賴注入,它也會找到 @PostConstruct@PreDestroy 註解標註的方法,並構建一個 LifecycleMetadata 對象,用於後續生命週期中的初始化和銷燬
    3. 設置該 RootBeanDefinition 被處理過,避免重複處理
  3. 提早暴露這個 bean,若是能夠的話,目的是解決單例模式 Bean 的循環依賴注入

    1. 判斷是否能夠提早暴露,知足三個條件:單例模式、容許循環依賴(默認爲 true)、當前單例 bean 正在被建立,在前面已經標記過
    2. 建立一個 ObjectFactory 實現類,用於返回當前正在被建立的 bean,提早暴露,保存在 singletonFactories三級 Map)緩存中

接下來開始初始化上面的 bean 實例對象,會先建立一個 Object exposedObject 等於 bean (引用)

  1. bean 進行屬性填充,注入對應的屬性值,調用 populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) 方法
  2. 初始化這個 exposedObject,調用其初始化方法,調用 initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) 方法

  1. 循環依賴注入的檢查

    1. 獲取當前正在建立的 beanName 被依賴注入的早期引用,調用 DefaultSingletonBeanRegistry#getSingleton(String beanName, boolean allowEarlyReference) 方法。注意,這裏有一個入參是 false,不會調用上面第 3 步的 ObjectFactory 實現類,也就是說當前 bean 若是出現循環依賴注入,這裏才能獲取到提早暴露的引用
    2. 若是出現了循環依賴注入,則進行接下來的檢查工做
      1. 若是 exposedObject 沒有在初始化階段中被改變,也就是沒有被加強,則使用提早暴露的那個引用
      2. 不然,exposedObject 已經不是被別的 Bean 依賴注入的那個 Bean,若是依賴當前 beanName 的 Bean(經過 depends-on 配置)已經被建立,則拋出異常
  2. 爲當前 bean 註冊 DisposableBeanAdapter(若是須要的話),用於 Bean 生命週期中的銷燬階段

  3. 返回建立好的 exposedObject 對象

歸納:

  • 首先獲取對應的 Class 對象,建立一個實例對象
  • 對這個實例對象進行屬性填充
  • 調用這個實例對象的初始化方法

關於上面建立 Bean 的兩個方法的相關步驟沒有展開討論,下面會依次進行分析

1. 建立 Class 對象

對應代碼段:

// AbstractAutowireCapableBeanFactory#createBean(...) 方法
// <1> 獲取 `mbd` 對應的 Class 對象,確保當前 Bean 可以被建立出來
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 若是這裏獲取到了 Class 對象,可是 `mbd` 中沒有 Class 對象的相關信息,表示這個 Class 對象是動態解析出來的
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    // 複製一份 `mbd`,並設置 Class 對象,由於動態解析出來的 Class 對象不被共享
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
}

建立一個 Java 對象以前,須要確保存在對應的 Class 對象。若是這裏獲取到了 Class 對象,可是 mbd 中沒有 Class 對象的相關信息,表示這個 Class 對象是動態解析出來的,則須要複製一份 mbd,並設置 Class 對象,由於動態解析出來的 Class 對象不被共享

resolveBeanClass 方法

resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch),獲取 beanName 的 Class 對象,方法以下:

// AbstractBeanFactory.java
@Nullable
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
        throws CannotLoadBeanClassException {
    try {
        // 有 Class 對象則直接返回
        if (mbd.hasBeanClass()) {
            return mbd.getBeanClass();
        }
        // 不然,調用 `doResolveBeanClass(...)` 方法,加載出一個 Class 對象
        if (System.getSecurityManager() != null) {
            return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> 
                                                 doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
        } else {
            return doResolveBeanClass(mbd, typesToMatch);
        }
    }
    // ... 省略 catch 各類異常
}

若是有 Class 對象則直接返回,沒有的話調用 doResolveBeanClass(...) 方法去獲取 Class 對象

doResolveBeanClass 方法

// AbstractBeanFactory.java
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
        throws ClassNotFoundException {
    // 獲取 ClassLoader 加載器
    ClassLoader beanClassLoader = getBeanClassLoader();
    ClassLoader dynamicLoader = beanClassLoader;
    boolean freshResolve = false;

    if (!ObjectUtils.isEmpty(typesToMatch)) {
        // When just doing type checks (i.e. not creating an actual instance yet),
        // use the specified temporary class loader (e.g. in a weaving scenario).
        ClassLoader tempClassLoader = getTempClassLoader();
        if (tempClassLoader != null) {
            dynamicLoader = tempClassLoader;
            freshResolve = true;
            if (tempClassLoader instanceof DecoratingClassLoader) {
                DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
                for (Class<?> typeToMatch : typesToMatch) {
                    dcl.excludeClass(typeToMatch.getName());
                }
            }
        }
    }

    // 獲取 `className`
    String className = mbd.getBeanClassName();
    if (className != null) {
        // 根據 BeanExpressionResolver 表達式處理器計算出 `className` 對應的結果
        // 可能仍是一個類名稱,也多是一個 Class 對象
        Object evaluated = evaluateBeanDefinitionString(className, mbd);
        if (!className.equals(evaluated)) {
            // A dynamically resolved expression, supported as of 4.2...
            if (evaluated instanceof Class) {
                return (Class<?>) evaluated;
            }
            else if (evaluated instanceof String) {
                className = (String) evaluated;
                freshResolve = true;
            }
            else {
                throw new IllegalStateException("Invalid class name expression result: " + evaluated);
            }
        }
        // 若是被處理過,則根據這個 `className` 建立一個 Class 對象
        // 建立的 Class 對象不會設置到 `mbd` 中
        if (freshResolve) {
            // When resolving against a temporary class loader, exit early in order
            // to avoid storing the resolved Class in the bean definition.
            if (dynamicLoader != null) {
                try {
                    return dynamicLoader.loadClass(className);
                }
                catch (ClassNotFoundException ex) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
                    }
                }
            }
            return ClassUtils.forName(className, dynamicLoader);
        }
    }

    // Resolve regularly, caching the result in the BeanDefinition...
    // 讓 RootBeanDefinition 本身解析出 Class 對象
    return mbd.resolveBeanClass(beanClassLoader);
}

暫時忽略上面具體的每一個細節,底層會根據 className 經過來加載器獲取對應的 Class 對象,並設置到 RootBeanDefinition

注意,這個過程多是動態解析出來的,例如 className 是一個表達式,經過 BeanDefinition 表達式解析器解析出來的,而後根據其獲取 Class 對象,這裏是不會設置到 RootBeanDefinition 中

2. MethodOverride 的驗證與準備

對應代碼段:

// AbstractAutowireCapableBeanFactory#createBean(...) 方法
try {
    // <2> 對全部的 MethodOverride 進行驗證和準備工做(確保存在對應的方法,並設置爲不能重複加載)
    mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
}

<lookup-method /><replace-method /> 標籤會被解析成 LookupOverride 和 ReplaceOverride 對象,用於實現或覆蓋某個方法,這裏會進行驗證和準備工做,過程以下:

// AbstractBeanDefinition.java
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
    // Check that lookup methods exist and determine their overloaded status.
    if (hasMethodOverrides()) { // 若是存在 `methodOverrides`
        // 獲取全部的 override method,遍歷進行處理
        getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
    }
}
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
    if (count == 0) {
        throw new BeanDefinitionValidationException(
                "Invalid method override: no method with name '" + mo.getMethodName() +
                "' on class [" + getBeanClassName() + "]");
    }
    else if (count == 1) {
        // Mark override as not overloaded, to avoid the overhead of arg type checking.
        mo.setOverloaded(false);
    }
}

確保這個類中存在對應的方法,並設置爲不能重複加載

3. 實例化前階段

對應代碼段:

// AbstractAutowireCapableBeanFactory#createBean(...) 方法
try {
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    /**
     * <3> 在實例化前進行相關處理,會先調用全部 {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}
     * 注意,若是這裏返回對象不是 `null` 的話,不會繼續往下執行本來初始化操做,直接返回,也就是說這個方法返回的是最終實例對象
     * 能夠經過這種方式提早返回一個代理對象,例如 AOP 的實現,或者 RPC 遠程調用的實現(由於本地類沒有遠程能力,能夠經過這種方式進行攔截)
     */
    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 執行,調用 resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) 方法進行處理,嘗試獲取一個代理對象

注意,若是這裏返回對象不是 null 的話,不會繼續往下執行本來初始化操做,直接返回,也就是說這個方法返回的是最終實例對象。能夠經過這種方式提早返回一個代理對象,例如 AOP 的實現,或者 RPC 遠程調用的實現(由於本地類沒有遠程能力,能夠經過這種方式進行攔截)

resolveBeforeInstantiation 方法

// AbstractAutowireCapableBeanFactory.java
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        // 若是 RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的),而且存在 InstantiationAwareBeanPostProcessor 處理器
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                 // 實例化前置處理
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // 後置處理
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

若是 RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的),而且存在 InstantiationAwareBeanPostProcessor 處理器,則進行下面的處理:

  1. 實例化前置處理,調用 applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) 方法,以下:

    @Nullable
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

    遍歷全部的 InstantiationAwareBeanPostProcessor 處理器,執行 postProcessBeforeInstantiation 方法,實例化前置處理,若是有一個處理後返回的結果不爲空則直接返回

  2. 若是第 1 步返回的對象不爲空,則調用 applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 方法,以下:

    // AbstractAutowireCapableBeanFactory.java
    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {
    
        Object result = existingBean;
        // 遍歷 BeanPostProcessor
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // 處理
            Object current = processor.postProcessAfterInitialization(result, beanName);
            // 返回空,則返回 result
            if (current == null) {
                return result;
            }
            // 修改 result
            result = current;
        }
        return result;
    }

    遍歷全部的 BeanPostProcessor 處理器,執行 postProcessAfterInitialization 方法,初始化後置處理

4. Bean 的實例化

對應代碼段:

// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法
// Instantiate the bean.
/**
 * <1> Bean 的實例化階段,會將 Bean 的實例對象封裝成 {@link BeanWrapperImpl} 包裝對象
 * BeanWrapperImpl 承擔的角色:
 * 1. Bean 實例的包裝
 * 2. {@link org.springframework.beans.PropertyAccessor} 屬性編輯器
 * 3. {@link org.springframework.beans.PropertyEditorRegistry} 屬性編輯器註冊表
 * 4. {@link org.springframework.core.convert.ConversionService} 類型轉換器(Spring 3+,替換了以前的 TypeConverter)
 */
BeanWrapper instanceWrapper = null;
// <1.1> 若是是單例模式,則先嚐試從 `factoryBeanInstanceCache` 緩存中獲取實例對象,並從緩存中移除
if (mbd.isSingleton()) {
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// <1.2> 使用合適的實例化策略來建立 Bean 的實例:工廠方法、構造函數自動注入、簡單初始化
// 主要是將 BeanDefinition 轉換爲 BeanWrapper 對象
if (instanceWrapper == null) {
    instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// <1.3> 獲取包裝的實例對象 `bean`
final Object bean = instanceWrapper.getWrappedInstance();
// <1.4> 獲取包裝的實例對象的類型 `beanType`
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
}

Bean 的實例化階段,會將 Bean 的實例對象封裝成 BeanWrapperImpl 包裝對象,BeanWrapperImpl 承擔的角色

  • Bean 實例的包裝
  • PropertyAccessor 屬性編輯器
  • PropertyEditorRegistry 屬性編輯器註冊表
  • ConversionService 類型轉換器(Spring 3+,替換了以前的 TypeConverter)

該過程大體以下

  1. 若是是單例模式,則先嚐試從 factoryBeanInstanceCache 緩存中獲取實例對象,並從緩存中移除
  2. 使用合適的實例化策略來建立 Bean 的實例:工廠方法、構造函數自動注入、簡單初始化,主要是將 BeanDefinition 轉換爲 BeanWrapper 對象,調用 createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 方法
  3. 獲取包裝的實例對象 bean
  4. 獲取包裝的實例對象的類型 beanType

createBeanInstance 方法

createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 方法,建立一個 Bean 的實例對象,以下:

// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    // <1> 獲取 `beanName` 對應的 Class 對象
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    // <2> 若是存在 Supplier 實例化回調接口,則使用給定的回調方法建立一個實例對象
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // <3> 若是配置了 `factory-method` 工廠方法,則調用該方法來建立一個實例對象
    // 經過 @Bean 標註的方法會經過這裏進行建立
    if (mbd.getFactoryMethodName() != null) {
        // 這個過程很是複雜,你能夠理解爲:
        // 找到最匹配的 Method 工廠方法,獲取相關參數(依賴注入),而後經過調用該方法返回一個實例對象(反射機制)
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    // <4> 判斷這個 RootBeanDefinition 的構造方法是否已經被解析出來了
    // 由於找到最匹配的構造方法比較繁瑣,找到後會設置到 RootBeanDefinition 中,避免重複這個過程
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) { // 加鎖
            // <4.1> 構造方法已經解析出來了
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                // <4.2> 這個構造方法有入參,表示須要先獲取到對應的入參(構造器注入)
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }

    // <5> 若是最匹配的構造方法已解析出來
    if (resolved) {
        // <5.1> 若是這個構造方法有入參
        if (autowireNecessary) {
            // 這個過程很複雜,你能夠理解爲:
            // 找到最匹配的構造方法,這裏會拿到已經被解析出來的這個方法,並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制)
            return autowireConstructor(beanName, mbd, null, null);
        }
        // <5.2> 不然,沒有入參
        else {
            // 直接調用解析出來構造方法,返回一個實例對象(反射機制)
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    // <6> 若是最匹配的構造方法還沒開始解析,那麼須要找到一個最匹配的構造方法,而後建立一個實例對象

    /**
     * <6.1> 嘗試經過 SmartInstantiationAwareBeanPostProcessor 處理器的 determineCandidateConstructors 方法來找到一些合適的構造方法
     * 參考 {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors}
     */
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // <6.2> 是否知足下面其中一個條件
    if (ctors != null // 上一步找到了合適的構造方法
            || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR // 構造器注入
            || mbd.hasConstructorArgumentValues() // 定義了構造方法的入參
            || !ObjectUtils.isEmpty(args)) // 當前方法指定了入參
    {
        // 找到最匹配的構造方法,若是 `ctors` 不爲空,會從這裏面找一個最匹配的,
        // 並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制)
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    /**
     * <7> 若是第 `6` 步還不知足,那麼嘗試獲取優先的構造方法
     * 參考 {@link org.springframework.context.support.GenericApplicationContext.ClassDerivedBeanDefinition}
     */
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        // 若是存在優先的構造方法,則從裏面找到最匹配的一個,並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制)
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    // <8> 若是上面多種狀況都不知足,那隻能使用兜底方法了,直接調用默認構造方法返回一個實例對象(反射機制)
    return instantiateBean(beanName, mbd);
}

過程大體以下:

  1. 獲取 beanName 對應的 Class 對象

  2. 若是存在 Supplier 實例化回調接口,則使用給定的回調方法建立一個實例對象

  3. 若是配置了 factory-method 工廠方法,則調用該方法來建立一個實例對象,經過 @Bean 標註的方法會經過這裏進行建立


若是上面兩種狀況都不是,那麼就進行接下來正常建立 Bean 實例的一個過程

  1. 判斷這個 RootBeanDefinition 的構造方法是否已經被解析出來了,由於找到最匹配的構造方法比較繁瑣,找到後會設置到 RootBeanDefinition 中,避免重複這個過程

    1. RootBeanDefinition 的 resolvedConstructorOrFactoryMethod 是否不爲空,不爲空表示構造方法已經解析出來了
    2. 構造方法已經解析出來了,則判斷它的 constructorArgumentsResolved 是否不爲空,不爲空表示有入參,須要先獲取到對應的入參(構造器注入)
  2. 若是最匹配的構造方法已解析出來

    1. 若是這個構造方法有入參,則找到最匹配的構造方法,這裏會拿到已經被解析出來的這個方法,並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制)
    2. 不然,沒有入參,直接調用解析出來構造方法,返回一個實例對象(反射機制)
  3. 若是最匹配的構造方法還沒開始解析,那麼須要找到一個最匹配的構造方法,而後建立一個實例對象

    1. 先嚐試經過 SmartInstantiationAwareBeanPostProcessor 處理器找到一些合適的構造方法,保存在 ctors

    2. 是否知足下面其中一個條件:ctors 不爲空、構造器注入模式、定義了構造方法的入參、當前方法指定了入參,

      則找到最匹配的構造方法,若是 ctors 不爲空,會從這裏面找一個最匹配的,並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制)

  4. 若是第 6 步還不知足,那麼嘗試從 RootBeanDefinition 中獲取優先的構造方法

    1. 若是存在優先的構造方法,則從裏面找到最匹配的一個,並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制)
  5. 若是上面多種狀況都不知足,那隻能使用兜底方法了,直接調用默認構造方法返回一個實例對象(反射機制)


整個的實例化過程很是的複雜,接下來進行歸納:

  • 先拿到對應 Class 對象

  • 若是設置了 Supplier 實例化回調接口,則經過該回調接口獲取實例對象

  • 若是配置了經過 factory-method 工廠方法獲取實例對象,則經過這個方法建立實例對象,@Bean 標註的方法也是經過這裏建立實例對象,方法入參會依賴注入

  • 找到最匹配的一個構造方法,並找到對應的入參(構造器注入),經過調用該方法返回一個實例對象

  • 兜底方法,調用默認構造方法建立一個實例對象

由於整個過程比較繁瑣,涉及到的方法行數比較多,因此另起一篇《Bean 的實例化階段》文章進行分析

5. 對 RootBeanDefinition 加工處理

對應代碼段:

// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法
// Allow post-processors to modify the merged bean definition.
// <2> 對 RootBeanDefinition(合併後)進行加工處理
synchronized (mbd.postProcessingLock) { // 加鎖,線程安全
    // <2.1> 若是該 RootBeanDefinition 沒有處理過,則進行下面的處理
    if (!mbd.postProcessed) {
        try {
            /**
             * <2.2> 對 RootBeanDefinition(合併後)進行加工處理
             * 調用全部 {@link MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition}
             * 【重要】例若有下面兩個處理器:
             * 1. AutowiredAnnotationBeanPostProcessor 會先解析出 @Autowired 和 @Value 註解標註的屬性的注入元信息,後續進行依賴注入;
             * 2. CommonAnnotationBeanPostProcessor 會先解析出 @Resource 註解標註的屬性的注入元信息,後續進行依賴注入,
             * 它也會找到 @PostConstruct 和 @PreDestroy 註解標註的方法,並構建一個 LifecycleMetadata 對象,用於後續生命週期中的初始化和銷燬
             */
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Post-processing of merged bean definition failed", ex);
        }
        // <2.3> 設置該 RootBeanDefinition 被處理過,避免重複處理
        mbd.postProcessed = true;
    }
}

在建立好實例對象後,容許你經過 MergedBeanDefinitionPostProcessor 處理器對該 RootBeanDefinition 進行加工處理,也能夠從中獲取相關信息

  1. 若是該 RootBeanDefinition 沒有加工處理過,則進行下面的處理,不然忽略該過程

  2. 對 RootBeanDefinition(合併後)進行加工處理,調用 applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) 方法,以下:

    // AbstractAutowireCapableBeanFactory.java
    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }

    調用全部 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition 方法對 RootBeanDefinition 進行加工處理,例如:AutowiredAnnotationBeanPostProcessor 會先解析出 @Autowired@Value 註解標註的屬性的注入元信息,後續進行依賴注入;CommonAnnotationBeanPostProcessor 會先解析出 @Resource 註解標註的屬性的注入元信息,後續進行依賴注入,它也會找到 @PostConstruct@PreDestroy 註解標註的方法,並構建一個 LifecycleMetadata 對象,用於後續生命週期中的初始化和銷燬

  3. 設置該 RootBeanDefinition 被處理過,避免重複處理

這個過程在後續講經過 @Autowired 依賴注入的實現原理會被提到

6. 提早暴露當前 Bean

對應代碼段:

// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// <3> 提早暴露這個 `bean`,若是能夠的話,目的是解決單例模式 Bean 的循環依賴注入
// <3.1> 判斷是否能夠提早暴露
boolean earlySingletonExposure = (mbd.isSingleton() // 單例模式
        && this.allowCircularReferences // 容許循環依賴,默認爲 true
        && isSingletonCurrentlyInCreation(beanName)); // 當前單例 bean 正在被建立,在前面已經標記過
if (earlySingletonExposure) {
    if (logger.isTraceEnabled()) {
        logger.trace("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
    }
    /**
     * <3.2>
     * 建立一個 ObjectFactory 實現類,用於返回當前正在被建立的 `bean`,提早暴露,保存在 `singletonFactories` (**三級 Map**)緩存中
     *
     * 能夠回到前面的 {@link AbstractBeanFactory#doGetBean#getSingleton(String)} 方法
     * 加載 Bean 的過程會先從緩存中獲取單例 Bean,能夠避免單例模式 Bean 循環依賴注入的問題
     */
    addSingletonFactory(beanName,
            // ObjectFactory 實現類
            () -> getEarlyBeanReference(beanName, mbd, bean));
}

在建立好實例對象後,此時尚未進行屬性的填充和初始化等工做,先判斷是否能夠提早暴露這個實例對象,目的是解決單例模式 Bean 的循環依賴注入

  1. 判斷是否能夠提早暴露,知足這些條件:單例模式、容許循環依賴(默認爲 true)、當前單例 Bean 正在被建立(前面已經標記過)

  2. 若是能夠的話,先經過 Lambda 表達式建立一個 ObjectFactory 實現類,以下:

    // AbstractAutowireCapableBeanFactory.java
    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        if (!mbd.isSynthetic() // RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的)
            && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                }
            }
        }
        return exposedObject;
    }

    入參 bean 爲當前 Bean 的實例對象(未初始化),這個實現類容許經過 SmartInstantiationAwareBeanPostProcessor 對這個提早暴露的對象進行處理,最終會返回這個提早暴露的對象

  3. 而後調用 addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) 方法,以下:

    // DefaultSingletonBeanRegistry.java
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized (this.singletonObjects) {
            if (!this.singletonObjects.containsKey(beanName)) {
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }
        }
    }

    能夠看到會往 singletonFactories 集合(三級 Map)中添加當前 beanNamesingletonFactory(ObjectFactory 實現類)的映射關係;

    earlySingletonObjects 集合(二級 Map)中移除當前 beanName

    registeredSingletons 集合(已註冊的 Bean 的名稱集合)中添加當前 beanName

能夠回到《開啓 Bean 的加載》文章中2. 從緩存中獲取單例 Bean小節,當這個 Bean 出現循環依賴注入了,是否是能夠避免相關問題,由於能夠經過這個 ObjectFactory 實現類獲取到提早暴露的對象

由於循環依賴注入的處理貫穿整個 Bean 的加載過程,因此另起一篇《單例 Bean 的循環依賴處理》文章進行分析

7. 屬性填充

對應代碼段:

// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法
// Initialize the bean instance.
// 開始初始化 `bean`
Object exposedObject = bean;
try {
    // <4> 對 `bean` 進行屬性填充,注入對應的屬性值
    populateBean(beanName, mbd, instanceWrapper);
    // <5> 初始化這個 `exposedObject`,調用其初始化方法
    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);
    }
}

在建立好實例對象後,這個對象的屬性尚未賦值,因此將這個實例對象的相關屬性進行賦值,也就是上面的第 <4>

populateBean 方法

populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) 方法,屬性填充,以下:

// AbstractAutowireCapableBeanFactory.java
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // <1> 若是實例對象爲空,則進行下面的判斷
    if (bw == null) {
        // <1.1> 這個 Bean 有屬性,則拋出異常
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        // <1.2> 不然,不用屬性填充,直接 `return`
        else {
            // Skip property population phase for null instance.
            return;
        }
    }

    // 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.
    // <2> 實例化階段的後置處理,若是知足這兩個條件
    if (!mbd.isSynthetic() // RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的)
            && hasInstantiationAwareBeanPostProcessors()) { // 是否有 InstantiationAwareBeanPostProcessor 處理器
        // <2.1> 遍歷全部的 BeanPostProcessor
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            // 若是爲 InstantiationAwareBeanPostProcessor 類型
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // <2.2> 對實例化對象進行後置處理
                // 注意若是返回 false,直接 `return`,不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    }

    // <3> 獲取 `pvs`,承載當前對象的屬性值
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    // <4> 獲取這個 Bean 的注入模式,默認爲 **AUTOWIRE_NO**,例如能夠經過 `@Bean` 註解的 `autowire` 屬性配置注入模式
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    // <4.1> 若是注入模式爲 **AUTOWIRE_BY_NAME** 或者 **AUTOWIRE_BY_TYPE**,則經過下面的方式獲取屬性值
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        // <4.2> 將 `pvs` 封裝成 MutablePropertyValues 對象 `newPvs`(容許對屬性進行相關操做)
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        // <4.3> **AUTOWIRE_BY_NAME** 模式,經過名稱獲取相關屬性值,保存在 `newPvs` 中
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        // <4.4> **AUTOWIRE_BY_TYPE** 模式,經過類型獲取相關屬性值,保存在 `newPvs` 中
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        // <4.5> 將 `newPvs` 複製給 `pvs`
        pvs = newPvs;
    }

    // 是否有 InstantiationAwareBeanPostProcessor 處理器
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 是否須要進行依賴檢查,默認爲 true
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    // <5> 經過 InstantiationAwareBeanPostProcessor 處理器(若是有)對 `pvs` 進行處理
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }

        // <5.1> 遍歷全部的 BeanPostProcessor
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            // 若是爲 InstantiationAwareBeanPostProcessor 類型
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                /**
                 * Spring 內部的 InstantiationAwareBeanPostProcessor 處理器:
                 * {@link AutowiredAnnotationBeanPostProcessor#postProcessProperties} 會解析 @Autowired 和 @Value 註解標註的屬性,獲取對應屬性值;
                 * {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties} 會 解析 Resource 註解標註的屬性,獲取對應的屬性值
                 */
                // <5.2> 調用處理器的 `postProcessProperties(...)` 方法,對 `pvs` 進行後置處理
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                // <5.3> 若是上一步的處理結果爲空,多是新版本致使的(Spring 5.1 以前沒有上面這個方法),則須要兼容老版本
                if (pvsToUse == null) {
                    // <5.3.1> 找到這個 Bean 的全部 `java.beans.PropertyDescriptor` 屬性描述器(包含這個屬性的全部信息)
                    if (filteredPds == null) {
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    // <5.3.2> 調用處理器的 `postProcessPropertyValues(...)` 方法,對 `pvs` 進行後置處理
                    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    // <5.3.3> 若是處理後的 PropertyValues 對象爲空,直接 `return`,則不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充
                    if (pvsToUse == null) {
                        return;
                    }
                }
                // <5.4> 將處理後的 `pvsToUse` 複製給 `pvs`
                pvs = pvsToUse;
            }
        }
    }
    // <6> 依賴檢查
    if (needsDepCheck) {
        // <6.1> 找到這個 Bean 的全部 `java.beans.PropertyDescriptor` 屬性描述器(包含這個屬性的全部信息)
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        // <6.2> 依賴檢查,若是沒有找到對應的屬性值,則根據檢查策略進行拋出異常(默認不會)
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    // <7> 若是 `pvs` 不爲空,則將裏面的屬性值設置到當前 Bean 對應的屬性中(依賴注入)
    // 前面找到的屬性值並無設置到 Bean 中,且屬性值多是一個表達式,類型也可能也不對,須要先進行處理和類型轉換,而後再設置到該實例對象中
    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

過程大體以下:

  1. 若是實例對象爲null,則進行下面的判斷

    1. 這個 Bean 有屬性,則拋出異常
    2. 不然,不用屬性填充,直接 return
  2. 實例化階段的後置處理,若是知足這兩個條件:RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的)、是否有 InstantiationAwareBeanPostProcessor 處理器

    1. 遍歷全部的 BeanPostProcessor

    2. 若是爲 InstantiationAwareBeanPostProcessor 類型,則對實例化對象進行後置處理

      注意,若是返回 false,直接 return,不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充

  3. 獲取 pvs,承載當前對象的屬性值

  4. 獲取這個 Bean 的注入模式,默認爲 AUTOWIRE_NO,例如能夠經過 @Bean 註解的 autowire 屬性配置注入模式

    1. 若是注入模式爲 AUTOWIRE_BY_NAME 或者 AUTOWIRE_BY_TYPE,則經過下面的方式獲取屬性值
    2. pvs 封裝成 MutablePropertyValues 對象 newPvs(容許對屬性進行相關操做)
    3. AUTOWIRE_BY_NAME 模式,經過名稱獲取相關屬性值,保存在 newPvs 中,調用 autowireByName(...) 方法
    4. AUTOWIRE_BY_TYPE 模式,經過類型獲取相關屬性值,保存在 newPvs 中,調用 autowireByType(...) 方法
    5. newPvs 複製給 pvs
  5. 經過 InstantiationAwareBeanPostProcessor 處理器(若是有)對 pvs 進行處理

    1. 遍歷全部的 BeanPostProcessor
    2. 若是爲 InstantiationAwareBeanPostProcessor 類型,則調用其 postProcessProperties(...) 方法,對 pvs 進行後置處理
    3. 若是上一步的處理結果爲空,多是新版本致使的(Spring 5.1 以前沒有上面這個方法),則須要兼容老版本
      1. 嘗試找到這個 Bean 的全部 java.beans.PropertyDescriptor 屬性描述器(包含這個屬性的全部信息)
      2. 調用處理器的 postProcessPropertyValues(...) 方法,對 pvs 進行後置處理
      3. 若是處理後的 PropertyValues 對象爲空,直接 return,則不會調用後面的處理器,也不會進行接下來的屬性填充
    4. 將處理後的 pvsToUse 複製給 pvs
  6. 依賴檢查

    1. 找到這個 Bean 的全部 java.beans.PropertyDescriptor 屬性描述器(包含這個屬性的全部信息)
    2. 進行依賴檢查,若是沒有找到對應的屬性值,則根據檢查策略進行拋出異常(默認不會)
  7. 若是 pvs 不爲空,則將裏面的屬性值設置到當前 Bean 對應的屬性中(依賴注入),調用 applyPropertyValues(...) 方法

    前面找到的屬性值並無設置到 Bean 中,且屬性值多是一個表達式,類型也可能也不對,須要先進行處理和類型轉換,而後再設置到該實例對象中


整個的屬性填充過程很是的複雜,接下來進行歸納:

  • 容許你對實例化對象進行後置處理,處理結果爲 false 表示不須要進行接下來的屬性填充過程
  • 根據注入模式,找到沒有配置屬性值的對象屬性,而後找到對應的 Bean,默認注入模式爲不注入
  • 容許你對屬性值進行後置處理,例如 @Autowired@Value 等註解標註的屬性會經過這裏找到對應的屬性值(或對象)
  • 上述過程僅找到了屬性值,還沒設置到當前實例對象中,因此最後一步纔是真正的屬性填充

由於整個過程比較繁瑣,涉及到的方法行數比較多,因此另起一篇《Bean 的屬性填充階段》文章進行分析

8. 初始化 Bean

對應代碼段:

// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法
// Initialize the bean instance.
// 開始初始化 `bean`
Object exposedObject = bean;
try {
    // <4> 對 `bean` 進行屬性填充,注入對應的屬性值
    populateBean(beanName, mbd, instanceWrapper);
    // <5> 初始化這個 `exposedObject`,調用其初始化方法
    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);
    }
}

實例對象已經有了,且相關屬性已經填充了,那麼接下來須要進行相關初始化工做,也就是上面的第 <5>

initializeBean

// AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) { // 安全模式
        // <1> Aware 接口的回調
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        // <1> Aware 接口的回調
        invokeAwareMethods(beanName, bean);
    }

    /**
     * <2> **初始化**階段的**前置處理**,執行全部 BeanPostProcessor 的 postProcessBeforeInitialization 方法
     *
     * 在 {@link AbstractApplicationContext#prepareBeanFactory} 方法中會添加 {@link ApplicationContextAwareProcessor} 處理器
     * 用於處理其餘 Aware 接口的回調,例如ApplicationContextAware、EnvironmentAware、ApplicationEventPublisherAware
     *
     * 在 {@link AnnotationConfigUtils#registerAnnotationConfigProcessors} 方法中會註冊 {@link CommonAnnotationBeanPostProcessor} 處理器
     * 在這裏會執行 @PostConstruct 註解標註的方法
     */
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // <3> 激活自定義的初始化方法
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }

    /**
     * <4> **初始化**階段的**後置處理**,執行全部 BeanPostProcessor 的 postProcessAfterInitialization 方法
     *
     * 在 {@link AbstractApplicationContext#prepareBeanFactory} 方法中會添加 {@link ApplicationListenerDetector} 處理器
     * 若是是單例 Bean 且爲 ApplicationListener 類型,則添加到 Spring 應用上下文,和 Spring 事件相關
     */
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

初始化過程以下:

  1. Aware 接口的回調,調用 invokeAwareMethods(final String beanName, final Object bean) 方法,以下:

    // AbstractAutowireCapableBeanFactory.java
    private void invokeAwareMethods(final String beanName, final Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
        }
    }

    若是是 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware,則調用其 setXxx 方法

  2. 初始化階段的前置處理,執行全部 BeanPostProcessor 的 postProcessBeforeInitialization 方法,以下:

    // AbstractAutowireCapableBeanFactory.java
    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
    
        Object result = existingBean;
        // 遍歷全部 BeanPostProcessor
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // 初始化的前置處理,返回 `current` 處理結果
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            // 處理結果爲空,則直接返回 `result`
            if (current == null) {
                return result;
            }
            // 不然,`result` 複製 `current`
            result = current;
        }
        return result;
    }

    例如 Spring 內部有下面兩個處理器

    ApplicationContextAwareProcessor:ApplicationContextAware、ApplicationEventPublisherAware、EnvironmentAware 等其餘 Aware 接口的回調

    CommonAnnotationBeanPostProcessor@PostConstruct 註解標註的方法的調用

  3. 激活自定義的初始化方法,以下:

    protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {
        // <1> InitializingBean 接口的回調(若是是)
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) { // 安全模式
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        // 調用其 afterPropertiesSet() 方法
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                } catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            } else {
                // 調用其 afterPropertiesSet() 方法
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }
        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) 
                && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) 
                && !mbd.isExternallyManagedInitMethod(initMethodName)) {
                // <2> 調用經過 `init-method` 指定的初始化方法(反射機制)
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }
    1. InitializingBean 接口的回調(若是是),調用其 afterPropertiesSet() 方法
    2. 調用經過 init-method 指定的初始化方法(反射機制)
  4. 初始化階段的後置處理,執行全部 BeanPostProcessor 的 postProcessAfterInitialization 方法,以下:

    // AbstractAutowireCapableBeanFactory.java
    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {
        Object result = existingBean;
        // 遍歷全部 BeanPostProcessor
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            // 初始化的後置處理,返回 `current` 處理結果
            Object current = processor.postProcessAfterInitialization(result, beanName);
            // 處理結果爲空,則直接返回 `result`
            if (current == null) {
                return result;
            }
            // 不然,`result` 複製 `current`
            result = current;
        }
        return result;
    }

    例如 Spring 內部有一個 ApplicationListenerDetector 處理器,若是是單例 Bean 且爲 ApplicationListener 類型,則添加到 Spring 應用上下文,和 Spring 事件相關


整個的初始化過程並不複雜,其中也有對應的擴展點,初始化前置處理和後置處理,總的歸納以下:

  1. Aware 接口的回調

  2. JSR-250 @PostConstruct 標註的方法的調用

  3. InitializingBean#afterPropertiesSet 方法的回調

  4. init-method 初始化方法的調用

9. 循環依賴注入的檢查

對應代碼段:

// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法
// <6> 循環依賴注入的檢查
if (earlySingletonExposure) {
    // <6.1> 獲取當前正在建立的 `beanName` 被依賴注入的早期引用
    // 注意,這裏有一個入參是 `false`,不會調用上面第 `3` 步的 ObjectFactory 實現類
    // 也就是說當前 `bean` 若是出現循環依賴注入,這裏才能獲取到提早暴露的引用
    Object earlySingletonReference = getSingleton(beanName, false);
    // <6.2> 若是出現了循環依賴注入,則進行接下來的檢查工做
    if (earlySingletonReference != null) {
        // <6.2.1> 若是 `exposedObject` 沒有在初始化階段中被改變,也就是沒有被加強
        // 則使用提早暴露的那個引用
        if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
        }
        // <6.2.2> 不然,`exposedObject` 已經不是被別的 Bean 依賴注入的那個 Bean
        else if (!this.allowRawInjectionDespiteWrapping // 是否容許注入未加工的 Bean,默認爲 false,這裏取非就爲 true
                && hasDependentBean(beanName)) { // 存在依賴 `beanName` 的 Bean(經過 `depends-on` 配置)
            // 獲取依賴當前 `beanName` 的 Bean 們的名稱(經過 `depends-on` 配置)
            String[] dependentBeans = getDependentBeans(beanName);
            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
            // 接下來進行判斷,若是依賴 `beanName` 的 Bean 已經建立
            // 說明當前 `beanName` 被注入了,而這裏最終的 `bean` 被包裝過,不是以前被注入的
            // 則拋出異常
            for (String dependentBean : dependentBeans) {
                if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                    actualDependentBeans.add(dependentBean);
                }
            }
            if (!actualDependentBeans.isEmpty()) {
                throw new BeanCurrentlyInCreationException(beanName,
                        "Bean with name '" + beanName + "' has been injected into other beans [" +
                        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                        "] in its raw version as part of a circular reference, but has eventually been " +
                        "wrapped. This means that said other beans do not use the final version of the " +
                        "bean. This is often the result of over-eager type matching - consider using " +
                        "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
            }
        }
    }
}

在前面 6. 提早暴露當前 Bean 小節中,若是提早暴露了 Bean,則可能存在循環依賴注入,這裏須要進行一些檢查,過程大體以下:

  1. 獲取當前正在建立的 beanName 被依賴注入的早期引用,這裏調用方法也就是從緩存中獲取單例 Bean 的方法。

    注意,這裏有一個入參是 false,不會調用前面 6. 提早暴露當前 Bean 小節中緩存的 ObjectFactory 實現類,也就是說當前 bean 若是出現循環依賴注入,這裏才能獲取到提早暴露的引用

  2. 若是上一步獲取到了提早暴露的引用,也就是出現了循環依賴注入,則進行接下來的檢查工做

    1. 若是 exposedObject 沒有在初始化階段中被改變,也就是沒有被加強,則使用提早暴露的那個引用
    2. 不然,exposedObject 已經不是被別的 Bean 依賴注入的那個 Bean,則進行相關判斷

當出現循環依賴注入,這裏會檢查填充屬性和初始化的過程當中是否改變了這個 beanName,改變了的話須要判斷依賴當前 beanName 的 Bean 們是否已經建立了,若是已經建立了,那麼可能它拿到的 beanName 不是這裏初始化後的對象(被修改了),因此須要拋出異常

10. 註冊可銷燬的 Bean

對應代碼段:

// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法
// Register bean as disposable.
try {
    /**
     * <7> 爲當前 `bean` 註冊 DisposableBeanAdapter(若是須要的話),用於 Bean 生命週期中的銷燬階段
     * 能夠看到 {@link DefaultSingletonBeanRegistry#destroySingletons()} 方法
     */
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
    throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

這裏會調用 registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) 方法,以下:

// AbstractBeanFactory.java
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    if (!mbd.isPrototype() // 不是原型模式
            && requiresDestruction(bean, mbd)) // 有銷燬的必要,也就是定義了銷燬方法
    {
        if (mbd.isSingleton()) { // 單例模式
            // Register a DisposableBean implementation that performs all destruction work for the given bean: 
            // DestructionAwareBeanPostProcessors, DisposableBean interface, custom destroy method.
            // 建立一個 DisposableBeanAdapter 對象封裝這個 Bean,而後保存在 `disposableBeans` Map 集合中
            registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
        else { // 其餘模式
            // A bean with a custom scope...
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            // 建立一個 DisposableBeanAdapter 對象封裝這個 Bean,往其餘模式的 Scope 對象裏面註冊
            scope.registerDestructionCallback(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
    }
}

若是不是原型模式,而且有銷燬的必要,也就是定義了銷燬方法,則須要建立一個 DisposableBeanAdapter 對象封裝這個 Bean,在生命週期的銷燬階段須要先經過這個對象先執行銷燬方法,這個對象如何存儲的:

  • 單例模式:保存在 disposableBeans Map 集合中
  • 其餘模式:往 Scope 對象裏面註冊

11. 返回 Bean

通過上面一系列的過程,實例化、屬性填充、初始化等階段,已經建立好了這個 Bean,最後直接返回

總結

當咱們顯示或者隱式地調用AbstractBeanFactorygetBean(...) 方法時,會觸發 Bean 的加載,加載過程在上一篇《開啓 Bean 的加載》文章中已經分析過。對於不一樣做用域的 Bean,底層都會調用 AbstractAutowireCapableBeanFactorycreateBean(...) 方法進行建立,建立 Bean 的過程以下:

  • Class 對象加載階段
  • 實例化前階段(若是返回了一個對象則直接返回,不會進行下面的階段)
  • 實例化階段
  • 實例化後階段
  • 提早暴露單例 Bean(循環依賴處理的關鍵)
  • 屬性填充階段
  • Aware 接口回調階段
  • 初始化前階段
  • 初始化階段
  • 初始化後階段

建立 Bean 的過程很是複雜,在不一樣的階段都會講到 BeanPostProcessor(及其子類)的身影,Spring 內部不少功能都是基於該處理器接口實現的,固然開發者也能夠經過其進行拓展,使得框架變得很是靈活。其中 Bean 的實例化屬性填充兩個階段比較複雜,這裏沒有深刻分析,可參考後續文章。提早暴露單例 Bean 循環依賴處理的關鍵,後續文章也會再次分析

你是否還有疑問,例如咱們經常使用的 @Autowired、@Value、@Resource、@Bean、@Import、@ComponentScan 等註解會在哪被解析呢?

彆着急,後面的文章都會講到,咱們先把 Bean 的加載過程搞明白,而後再講 Spring 應用上下文的生命週期

相關文章
相關標籤/搜索