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


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

Spring 版本:5.1.14.RELEASE

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

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

Bean 的創建過程

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

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

AbstractAutowireCapableBeanFactory

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

【核心】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

過程大致如下:

  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 應用上下文的生命周期


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM