Spring的Bean的生命週期(源碼分析)

一、 BeanPostProcessor

接口定義

<code>package org.springframework.beans.factory.config;  
public interface BeanPostProcessor {  
   Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
   Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;  
}  /<code>

BeanPostProcessor是Spring容器的一個擴展點,可以進行自定義的實例化、初始化、依賴裝配、依賴檢查等流程,即可以覆蓋默認的實例化,也可以增強初始化、依賴注入、依賴檢查等流程,其javadoc有如下描述:

<code>e.g. checking for marker interfaces or wrapping them with proxies.

大體意思是可以檢查相應的標識接口完成一些自定義功能實現,如包裝目標對象到代理對象。/<code>

我們可以看到BeanPostProcessor一共有兩個回調方法postProcessBeforeInitialization和postProcessAfterInitialization,那這兩個方法會在什麼Spring執行流程中的哪個步驟執行呢?還有目前Spring提供哪些相應的實現呢?

Spring還提供了BeanPostProcessor一些其他接口實現,來完成除實例化外的其他功能,後續詳細介紹。

二、 通過源代碼看看創建一個Bean實例的具體執行流程

Spring的Bean的生命週期(源碼分析)

AbstractApplicationContext內部使用DefaultListableBeanFactory,且DefaultListableBeanFactory繼承AbstractAutowireCapableBeanFactory,因此我們此處分析AbstractAutowireCapableBeanFactory即可。

2.1 createBean

AbstractAutowireCapableBeanFactory的createBean方法代碼如下:

<code>protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {  
   resolveBeanClass(mbd, beanName); /1解析Bean的class  
   mbd.prepareMethodOverrides(); //2 方法注入準備  
   Object bean = resolveBeforeInstantiation(beanName, mbd); //3 第一個BeanPostProcessor擴展點  
   if (bean != null) { //4 如果3處的擴展點返回的bean不為空,直接返回該bean,後續流程不需要執行  
       return bean;  
  }  
   Object beanInstance = doCreateBean(beanName, mbd, args); //5 執行spring的創建bean實例的流程啦  
   return beanInstance;  
}  /<code>

2.2 resolveBeforeInstantiation

AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation方法代碼如下:

<code>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.  
           if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {  
               //3.1、執行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation回調方法  
               bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);  
               if (bean != null) {  
                   //3.2、執行InstantiationAwareBeanPostProcessor的postProcessAfterInitialization回調方法  
                   bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);  
              }  
          }  
           mbd.beforeInstantiationResolved = (bean != null);  
      }  
       return bean;  
} /<code>

2.3 doCreateBean

AbstractAutowireCapableBeanFactory的doCreateBean方法代碼如下:

<code>        // 6、通過BeanWrapper實例化Bean   
       BeanWrapper instanceWrapper = null;  
       if (mbd.isSingleton()) {  
           instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  
      }  
       if (instanceWrapper == null) {  
           instanceWrapper = createBeanInstance(beanName, mbd, args);  
      }  
       final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);  
       Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);  
 
       //7、執行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition流程  
       synchronized (mbd.postProcessingLock) {  
           if (!mbd.postProcessed) {  
               applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  
               mbd.postProcessed = true;  
          }  
      }  
       // 8、及早暴露單例Bean引用,從而允許setter注入方式的循環引用  
       boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&  
               isSingletonCurrentlyInCreation(beanName));  
       if (earlySingletonExposure) {  
           //省略log  
           addSingletonFactory(beanName, new ObjectFactory() {  
               public Object getObject() throws BeansException {  
                   //8.1、調用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference返回一個需要暴露的Bean(例如包裝目標對象到代理對象)  
                   return getEarlyBeanReference(beanName, mbd, bean);  
              }  
          });  
      }  
         
       Object exposedObject = bean;  
       try {  
           populateBean(beanName, mbd, instanceWrapper); //9、組裝-Bean依賴  
           if (exposedObject != null) {  
               exposedObject = initializeBean(beanName, exposedObject, mbd); //10、初始化Bean  
          }  
      }  

       catch (Throwable ex) {  
           //省略異常  
      }  
 
 
       //11如果是及早暴露單例bean,通過getSingleton觸發3.1處的getEarlyBeanReference調用獲取要及早暴露的單例Bean  
       if (earlySingletonExposure) {  
           Object earlySingletonReference = getSingleton(beanName, false);  
           if (earlySingletonReference != null) {  
               if (exposedObject == bean) {  
                   exposedObject = earlySingletonReference;  
              }  
               else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {  
                   String[] dependentBeans = getDependentBeans(beanName);  
                   Set<string> actualDependentBeans = new LinkedHashSet<string>(dependentBeans.length);  
                   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.");  
                  }  
              }  
          }  
      }  
       //12、註冊Bean的銷燬回調  
       try {  
           registerDisposableBeanIfNecessary(beanName, bean, mbd);  
      }  
       catch (BeanDefinitionValidationException ex) {  
           throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);  
      }  
 
       return exposedObject;  
}  /<string>/<string>/<code>

2.4 populateBean

AbstractAutowireCapableBeanFactory的populateBean方法代碼如下:

<code>//9、組裝-Bean  
protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {  
   PropertyValues pvs = mbd.getPropertyValues();  
   //省略部分代碼  
   //9.1、通過InstantiationAwareBeanPostProcessor擴展點允許自定義裝配流程(如@Autowired支持等)  
   //執行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation  
   boolean continueWithPropertyPopulation = true;  
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {  
       for (BeanPostProcessor bp : getBeanPostProcessors()) {  
           if (bp instanceof InstantiationAwareBeanPostProcessor) {  
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
               if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {  
                   continueWithPropertyPopulation = false;  
                   break;  
              }  
          }  
      }  
  }  
   if (!continueWithPropertyPopulation) {  
       return;  
  }  
   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
           mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
       MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
       // 9. 2、自動裝配(根據name/type)  
       if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {  
           autowireByName(beanName, mbd, bw, newPvs);  
      }  
       if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
           autowireByType(beanName, mbd, bw, newPvs);  
      }  
       pvs = newPvs;  
  }  
   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();  
   boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);  
 
 
   //9. 3、執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues  
   if (hasInstAwareBpps || needsDepCheck) {  
       PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);  
       if (hasInstAwareBpps) {  
           for (BeanPostProcessor bp : getBeanPostProcessors()) {  
               if (bp instanceof InstantiationAwareBeanPostProcessor) {  
                   InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
                   pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);  

                   if (pvs == null) {  
                       return;  
                  }  
              }  
          }  
      }  
       //9. 4、執行依賴檢查  
       if (needsDepCheck) {  
           checkDependencies(beanName, mbd, filteredPds, pvs);  
      }  
  }  
   //9. 5、應用依賴注入  
   applyPropertyValues(beanName, mbd, bw, pvs);  
}  /<code>

2.5 initializeBean

AbstractAutowireCapableBeanFactory的initializeBean方法代碼如下:

<code>     //10、實例化Bean  
    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {  
//10.1、調用Aware接口注入(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)  
invokeAwareMethods(beanName, bean);//此處省略部分代碼  
//10.2、執行BeanPostProcessor擴展點的postProcessBeforeInitialization進行修改實例化Bean  
Object wrappedBean = bean;  
if (mbd == null || !mbd.isSynthetic()) {  
   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  
}  
//10.3、執行初始化回調(1、調用InitializingBean的afterPropertiesSet 2、調用自定義的init-method)  
try {  
   invokeInitMethods(beanName, wrappedBean, mbd);  
}  
catch (Throwable ex) {  
   //異常省略  
}  
//10.4、執行BeanPostProcessor擴展點的postProcessAfterInitialization進行修改實例化Bean  
if (mbd == null || !mbd.isSynthetic()) {  
   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  
}  
return wrappedBean;  /<code>

三、創建一個Bean實例的執行流程簡化:

protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args); 創建Bean

(1**、resolveBeanClass(mbd, beanName);** 解析Bean class,若class配置錯誤將拋出CannotLoadBeanClassException;


(2**、mbd.prepareMethodOverrides();** 準備和驗證配置的方法注入,若驗證失敗拋出BeanDefinitionValidationException

有關方法注入知識請參考【第三章】 DI 之 3.3 更多DI的知識 ——跟我學spring3 3.3.5 方法注入;


(3**、Object bean = resolveBeforeInstantiation(beanName, mbd);** 第一個BeanPostProcessor擴展點,此處只執行InstantiationAwareBeanPostProcessor類型的BeanPostProcessor Bean;

(3.1、bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);執行InstantiationAwareBeanPostProcessor的實例化的預處理回調方法postProcessBeforeInstantiation(自定義的實例化,如創建代理);

(3.2、bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);執行InstantiationAwareBeanPostProcessor的實例化的後處理回調方法postProcessAfterInitialization(如依賴注入),如果3.1處返回的Bean不為null才執行;


(4**、如果3處的擴展點返回的bean不為空,直接返回該bean,後續流程不需要執行;**


(5**、Object beanInstance = doCreateBean(beanName, mbd, args);** 執行spring的創建bean實例的流程;


(6**、createBeanInstance(beanName, mbd, args);** 實例化Bean

(6.1、instantiateUsingFactoryMethod 工廠方法實例化;請參考【http://jinnianshilongnian.iteye.com/blog/1413857】

(6.2、構造器實例化,請參考【http://jinnianshilongnian.iteye.com/blog/1413857】;

(6.2.1、如果之前已經解析過構造器

(6.2.1.1 autowireConstructor:有參調用autowireConstructor實例化

(6.2.1.2、instantiateBean:無參調用instantiateBean實例化;

(6.2.2、如果之前沒有解析過構造器:


(6.2.2.1、通過SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors回調方法解析構造器,第二個BeanPostProcessor擴展點,返回第一個解析成功(返回值不為null)的構造器組,如AutowiredAnnotationBeanPostProcessor實現將自動掃描通過@Autowired/@Value註解的構造器從而可以完成構造器注入,請參考【第十二章】零配置 之 12.2 註解實現Bean依賴注入 ——跟我學spring3 ;

(6.2.2.2、autowireConstructor:如果(6.2.2.1返回的不為null,且是有參構造器,調用autowireConstructor實例化;

(6.2.2.3、instantiateBean: 否則調用無參構造器實例化;


(7**、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);**第三個BeanPostProcessor擴展點,執行Bean定義的合併;

(7.1、執行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition回調方法,進行bean定義的合併;


(8**、addSingletonFactory(beanName, new ObjectFactory() {**

<code>                        **public Object getObject() throws BeansException {**

                              **return getEarlyBeanReference(beanName, mbd, bean);**

                      **}**

                **});** 及早暴露單例Bean引用,從而允許setter注入方式的循環引用/<code>

(8.1、SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference;第四個BeanPostProcessor擴展點,當存在循環依賴時,通過該回調方法獲取及早暴露的Bean實例;


(9**、populateBean(beanName, mbd, instanceWrapper);**裝配Bean依賴

(9.1、InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation;第五個BeanPostProcessor擴展點,在實例化Bean之後,所有其他裝配邏輯之前執行,如果false將阻止其他的InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation的執行和從(9.2到(9.5的執行,通常返回true;

(9.2、autowireByName、autowireByType:根據名字和類型進行自動裝配,自動裝配的知識請參考【第三章】 DI 之 3.3 更多DI的知識 ——跟我學spring3 3.3.3 自動裝配;

(9.3、InstantiationAwareBeanPostProcessor的postProcessPropertyValues:第六個BeanPostProcessor擴展點,完成其他定製的一些依賴注入,如AutowiredAnnotationBeanPostProcessor執行@Autowired註解注入,CommonAnnotationBeanPostProcessor執行@Resource等註解的注入,PersistenceAnnotationBeanPostProcessor執行@ PersistenceContext等JPA註解的注入,RequiredAnnotationBeanPostProcessor執行@ Required註解的檢查等等,請參考【第十二章】零配置 之 12.2 註解實現Bean依賴注入 ——跟我學spring3;

(9.4、checkDependencies:依賴檢查,請參考【第三章】 DI 之 3.3 更多DI的知識 ——跟我學spring3 3.3.4 依賴檢查;

(9.5、applyPropertyValues:應用明確的setter屬性注入,請參考【第三章】 DI 之 3.1 DI的配置使用 ——跟我學spring3 ;


(10**、exposedObject = initializeBean(beanName, exposedObject, mbd);** 執行初始化Bean流程;

(10.1、invokeAwareMethods(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware):調用一些Aware標識接口注入如BeanName、BeanFactory;

(10.2、BeanPostProcessor的postProcessBeforeInitialization:第七個擴展點,在調用初始化之前完成一些定製的初始化任務,如BeanValidationPostProcessor完成JSR-303 @Valid註解Bean驗證,InitDestroyAnnotationBeanPostProcessor完成@PostConstruct註解的初始化方法調用,ApplicationContextAwareProcessor完成一些Aware接口的注入(如EnvironmentAware、ResourceLoaderAware、ApplicationContextAware),其返回值將替代原始的Bean對象;

(10.3、invokeInitMethods : 調用初始化方法;

(10.3.1、InitializingBean的afterPropertiesSet :調用InitializingBean的afterPropertiesSet回調方法;

(10.3.2、通過xml指定的自定義init-method :調用通過xml配置的自定義init-method

(10.3.3、BeanPostProcessor的postProcessAfterInitialization :第八個擴展點,AspectJAwareAdvisorAutoProxyCreator(完成xml風格的AOP配置(aop:config)的目標對象包裝到AOP代理對象)、AnnotationAwareAspectJAutoProxyCreator(完成@Aspectj註解風格(aop:aspectj-autoproxy @Aspect)的AOP配置的目標對象包裝到AOP代理對象),其返回值將替代原始的Bean對象;


(11、if (earlySingletonExposure) {

<code>                 Object earlySingletonReference = getSingleton(beanName, false);

……

} :如果是earlySingleExposure,調用getSingle方法獲取Bean實例;
/<code>

earlySingleExposure =(mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName))

只要單例Bean且允許循環引用(默認true)且當前單例Bean正在創建中

(11.1、如果是earlySingletonExposure調用getSingleton將觸發【8】處ObjectFactory.getObject()的調用,通過【8.1】處的getEarlyBeanReference獲取相關Bean(如包裝目標對象的代理Bean);(在循環引用Bean時可能引起Spring事務處理時自我調用的解決方案及一些實現方式的風險);


(12**、registerDisposableBeanIfNecessary(beanName, bean, mbd)** 註冊Bean的銷燬方法(只有非原型Bean可註冊);

(12.1、單例Bean的銷燬流程

(12.1.1、DestructionAwareBeanPostProcessor的postProcessBeforeDestruction : 第九個擴展點,如InitDestroyAnnotationBeanPostProcessor完成@PreDestroy註解的銷燬方法註冊和調用;

(12.1.2、DisposableBean的destroy:註冊/調用DisposableBean的destroy銷燬方法;

(12.1.3、通過xml指定的自定義destroy-method : 註冊/調用通過XML指定的destroy-method銷燬方法;

(12.1.2、Scope的registerDestructionCallback:註冊自定義的Scope的銷燬回調方法,如RequestScope、SessionScope等;其流程和【12.1 單例Bean的銷燬流程一樣】,關於自定義Scope請參考【第三章】 DI 之 3.4 Bean的作用域 ——跟我學spring3


(13**、到此Bean實例化、依賴注入、初始化完畢可以返回創建好的bean了。**


從上面的流程我們可以看到BeanPostProcessor一個使用了九個擴展點,其實還一個擴展點(SmartInstantiationAwareBeanPostProcessor的predictBeanType在下一篇介紹),接下來我們看看BeanPostProcessor這些擴展點都主要完成什麼功能及常見的BeanPostProcessor。

四、BeanPostProcessor接口及回調方法圖

Spring的Bean的生命週期(源碼分析)

從圖中我們可以看出一共五個接口,共十個回調方法,即十個擴展點,但我們之前的文章只分析了其中八個,另外兩個稍候也會解析一下是幹什麼的。

五、五個接口十個擴展點解析

1**、InstantiationAwareBeanPostProcessor**:實例化Bean後置處理器(繼承BeanPostProcessor)

postProcessBeforeInstantiation :在實例化目標對象之前執行,可以自定義實例化邏輯,如返回一個代理對象等,(3.1處執行;如果此處返回的Bean不為null將中斷後續Spring創建Bean的流程,且只執行postProcessAfterInitialization回調方法,如當AbstractAutoProxyCreator的實現者註冊了TargetSourceCreator(創建自定義的TargetSource)將改變執行流程,不註冊TargetSourceCreator我們默認使用的是SingletonTargetSource(即AOP代理直接保證目標對象),此處我們還可以使用如ThreadLocalTargetSource(線程綁定的Bean)、CommonsPoolTargetSource(實例池的Bean)等等,大家可以去spring官方文檔瞭解TargetSource詳情;

postProcessAfterInitialization : Bean實例化完畢後執行的後處理操作,所有初始化邏輯、裝配邏輯之前執行,如果返回false將阻止其他的InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation的執行,(3.2和(9.1處執行;在此處可以執行一些初始化邏輯或依賴裝配邏輯;

postProcessPropertyValues :完成其他定製的一些依賴注入和依賴檢查等,如AutowiredAnnotationBeanPostProcessor執行@Autowired註解注入,CommonAnnotationBeanPostProcessor執行@Resource等註解的注入,PersistenceAnnotationBeanPostProcessor執行@ PersistenceContext等JPA註解的注入,RequiredAnnotationBeanPostProcessor執行@ Required註解的檢查等等,(9.3處執行;


2**、MergedBeanDefinitionPostProcessor**:合併Bean定義後置處理器 (繼承BeanPostProcessor)

postProcessMergedBeanDefinition:執行Bean定義的合併,在(7.1處執行,且在實例化完Bean之後執行;


3**、SmartInstantiationAwareBeanPostProcessor**:智能實例化Bean後置處理器(繼承InstantiationAwareBeanPostProcessor)

predictBeanType:預測Bean的類型,返回第一個預測成功的Class類型,如果不能預測返回null;當你調用BeanFactory.getType(name)時當通過Bean定義無法得到Bean類型信息時就調用該回調方法來決定類型信息;BeanFactory.isTypeMatch(name, targetType)用於檢測給定名字的Bean是否匹配目標類型(如在依賴注入時需要使用);

determineCandidateConstructors:檢測Bean的構造器,可以檢測出多個候選構造器,再有相應的策略決定使用哪一個,如AutowiredAnnotationBeanPostProcessor實現將自動掃描通過@Autowired/@Value註解的構造器從而可以完成構造器注入,請參考【第十二章】零配置 之 12.2 註解實現Bean依賴注入 ——跟我學spring3 ,(6.2.2.1處執行;

getEarlyBeanReference:當正在創建A時,A依賴B,此時通過(8將A作為ObjectFactory放入單例工廠中進行early expose,此處B需要引用A,但A正在創建,從單例工廠拿到ObjectFactory(其通過getEarlyBeanReference獲取及早暴露Bean),從而允許循環依賴,此時AspectJAwareAdvisorAutoProxyCreator(完成xml風格的AOP配置(aop:config)將目標對象(A)包裝到AOP代理對象)或AnnotationAwareAspectJAutoProxyCreator(完成@Aspectj註解風格(aop:aspectj-autoproxy @Aspect)將目標對象(A)包裝到AOP代理對象),其返回值將替代原始的Bean對象,即此時通過early reference能得到正確的代理對象,(8.1處實施;如果此處執行了,(10.3.3處的AspectJAwareAdvisorAutoProxyCreator或AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization將不執行,即這兩個回調方法是二選一的;


4**、BeanPostProcessor**:Bean後置處理器

postProcessBeforeInitialization:實例化、依賴注入完畢,在調用顯示的初始化之前完成一些定製的初始化任務,如BeanValidationPostProcessor完成JSR-303 @Valid註解Bean驗證,InitDestroyAnnotationBeanPostProcessor完成@PostConstruct註解的初始化方法調用,ApplicationContextAwareProcessor完成一些Aware接口的注入(如EnvironmentAware、ResourceLoaderAware、ApplicationContextAware),其返回值將替代原始的Bean對象;(10.2處執行;

postProcessAfterInitialization:實例化、依賴注入、初始化完畢時執行,如AspectJAwareAdvisorAutoProxyCreator(完成xml風格的AOP配置(aop:config)的目標對象包裝到AOP代理對象)、AnnotationAwareAspectJAutoProxyCreator(完成@Aspectj註解風格(aop:aspectj-autoproxy @Aspect)的AOP配置的目標對象包裝到AOP代理對象),其返回值將替代原始的Bean對象;(10.3.3處執行;此處需要參考getEarlyBeanReference;


5**、DestructionAwareBeanPostProcessor**:銷燬Bean後置處理器(繼承BeanPostProcessor)

postProcessBeforeDestruction:銷燬後處理回調方法,該回調只能應用到單例Bean,如InitDestroyAnnotationBeanPostProcessor完成@PreDestroy註解的銷燬方法調用;(12.1.1處執行。

六、內置的一些BeanPostProcessor

Spring的Bean的生命週期(源碼分析)

此圖只有內置的一部分。


1、ApplicationContextAwareProcessor

容器啟動時會自動註冊。注入那些實現ApplicationContextAware、MessageSourceAware、ResourceLoaderAware、EnvironmentAware、

EmbeddedValueResolverAware、ApplicationEventPublisherAware標識接口的Bean需要的相應實例,在postProcessBeforeInitialization回調方法中進行實施,即(10.2處實施。


2、CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor繼承InitDestroyAnnotationBeanPostProcessor,當在配置文件有context:annotation-config或context:component-scan會自動註冊。


提供對JSR-250規範註解的支持@javax.annotation.Resource、@javax.annotation.PostConstruct和@javax.annotation.PreDestroy等的支持。


2.1、通過@Resource註解進行依賴注入:

<code>postProcessPropertyValues:通過此回調進行@Resource註解的依賴注入;(9.3處實施;/<code>

2.2、用於執行@PostConstruct 和@PreDestroy 註解的初始化和銷燬方法的擴展點:

<code>postProcessBeforeInitialization()將會調用bean的@PostConstruct方法;(10.2處實施; 


postProcessBeforeDestruction()將會調用單例 Bean的@PreDestroy方法(此回調方法會在容器銷燬時調用),(12.1.1處實施。/<code>


詳見【第十二章】零配置 之 12.2 註解實現Bean依賴注入 ——跟我學spring3,JSR-250註解部分。


3、AutowiredAnnotationBeanPostProcessor

當在配置文件有context:annotation-config或context:component-scan會自動註冊。


提供對JSR-330規範註解的支持和Spring自帶註解的支持。


3.1、Spring自帶註解的依賴注入支持,@Autowired和@Value:

<code>determineCandidateConstructors :決定候選構造器;詳見【12.2中的構造器注入】;(6.2.2.1處實施;
/<code>

postProcessPropertyValues :進行依賴注入;詳見【12.2中的字段注入和方法參數注入】;(9.3處實施;

3.2、對JSR-330規範註解的依賴注入支持,@Inject:

<code>同2.1類似只是查找使用的註解不一樣; 

/<code>


詳見【第十二章】零配置 之 12.2 註解實現Bean依賴注入 ——跟我學spring3,Spring自帶依賴注入註解和 JSR-330註解部分。


4、RequiredAnnotationBeanPostProcessor

當在配置文件有context:annotation-config或context:component-scan會自動註冊。


4.1、提供對@ Required註解的方法進行依賴檢查支持:

<code>postProcessPropertyValues:如果檢測到沒有進行依賴注入時拋出BeanInitializationException異常;(9.3處實施;
/<code>


詳見【第十二章】零配置 之 12.2 註解實現Bean依賴注入 ——跟我學spring3,@Required**:依賴檢查**。


5、PersistenceAnnotationBeanPostProcessor

當在配置文件有context:annotation-config或context:component-scan會自動註冊。


5.1、通過對JPA @ javax.persistence.PersistenceUnit和@ javax.persistence.PersistenceContext註解進行依賴注入的支持;

<code>postProcessPropertyValues : 根據@PersistenceUnit/@PersistenceContext進行EntityManagerFactory和EntityManager的支持;
/<code>


6、AbstractAutoProxyCreator

AspectJAwareAdvisorAutoProxyCreator和AnnotationAwareAspectJAutoProxyCreator都是繼承AbstractAutoProxyCreator,AspectJAwareAdvisorAutoProxyCreator提供對(aop:config)聲明式AOP的支持,AnnotationAwareAspectJAutoProxyCreator提供對(aop:aspectj-autoproxy)註解式(@AspectJ)AOP的支持,因此只需要分析AbstractAutoProxyCreator即可。


當使用aop:config配置時自動註冊AspectJAwareAdvisorAutoProxyCreator,而使用aop:aspectj-autoproxy時會自動註冊AnnotationAwareAspectJAutoProxyCreator。

6.1、predictBeanType:預測Bean的類型,如果目標對象被AOP代理對象包裝,此處將返回AOP代理對象的類型;

<code>public Class> predictBeanType(Class> beanClass, String beanName) {  
Object cacheKey = getCacheKey(beanClass, beanName);
return this.proxyTypes.get(cacheKey); //獲取代理對象類型,可能返回null
}
/<code>

6.2、postProcessBeforeInstantiation:

<code>public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {  
   //1、得到一個緩存的唯一key(根據beanClass和beanName生成唯一key)  
   Object cacheKey = getCacheKey(beanClass, beanName);  
   //2、如果當前targetSourcedBeans(通過自定義TargetSourceCreator創建的TargetSource)不包含cacheKey  

   if (!this.targetSourcedBeans.contains(cacheKey)) {  
       //2.1、advisedBeans(已經被增強的Bean,即AOP代理對象)中包含當前cacheKey或nonAdvisedBeans(不應該被增強的Bean)中包含當前cacheKey 返回null,即走Spring默認流程  
       if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) {  
           return null;  
      }  
       //2.2、如果是基礎設施類(如Advisor、Advice、AopInfrastructureBean的實現)不進行處理  
       //2.2、shouldSkip 默認false,可以生成子類覆蓋,如AspectJAwareAdvisorAutoProxyCreator覆蓋   (if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) return true; 即如果是自己就跳過)  
       if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {  
           this.nonAdvisedBeans.add(cacheKey);//在不能增強的Bean列表緩存當前cacheKey  
           return null;  
      }  
  }  
 
   //3、開始創建AOP代理對象  
   //3.1、配置自定義的TargetSourceCreator進行TargetSource創建  
   TargetSource targetSource = getCustomTargetSource(beanClass, beanName);  
   if (targetSource != null) {  
       //3.2、如果targetSource不為null 添加到targetSourcedBeans緩存,並創建AOP代理對象  
       this.targetSourcedBeans.add(beanName);  
       // specificInterceptors即增強(包括前置增強、後置增強等等)  
       Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);  
       //3.3、創建代理對象  
       Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);  
       //3.4、將代理類型放入proxyTypes從而允許後續的predictBeanType()調用獲取  
       this.proxyTypes.put(cacheKey, proxy.getClass());  
       return proxy;  
  }  
   return null;  
}  /<code>

從如上代碼可以看出,當我們配置TargetSourceCreator進行自定義TargetSource創建時,會創建代理對象並中斷默認Spring創建流程。

6.3、getEarlyBeanReference

<code>//獲取early Bean引用(只有單例Bean才能回調該方法)  
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//1、將cacheKey添加到earlyProxyReferences緩存,從而避免多次重複創建
this.earlyProxyReferences.add(cacheKey);
//2、包裝目標對象到AOP代理對象(如果需要)
return wrapIfNecessary(bean, beanName, cacheKey);
}
/<code>

6.4、postProcessAfterInitialization

<code>public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//1、如果之前調用過getEarlyBeanReference獲取包裝目標對象到AOP代理對象(如果需要),則不再執行
if (!this.earlyProxyReferences.contains(cacheKey)) {
//2、包裝目標對象到AOP代理對象(如果需要)
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
/<code>
<code>protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {  
if (this.targetSourcedBeans.contains(beanName)) {//通過TargetSourceCreator進行自定義TargetSource不需要包裝
return bean;
}
if (this.nonAdvisedBeans.contains(cacheKey)) {//不應該被增強對象不需要包裝
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {//基礎設施/應該skip的不需要保證

this.nonAdvisedBeans.add(cacheKey);
return bean;
}

// 如果有增強就執行包裝目標對象到代理對象
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.add(cacheKey);//將cacheKey添加到已經被增強列表,防止多次增強
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));//創建代理對象
this.proxyTypes.put(cacheKey, proxy.getClass());//緩存代理類型
return proxy;
}
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
/<code>

從如上流程可以看出 getEarlyBeanReference和postProcessAfterInitialization是二者選一的,而且單例Bean目標對象只能被增強一次,而原型Bean目標對象可能被包裝多次。

7、BeanValidationPostProcessor

默認不自動註冊,Spring3.0開始支持。

提供對JSR-303驗證規範支持。

根據afterInitialization是false/true決定調用postProcessBeforeInitialization或postProcessAfterInitialization來通過JSR-303規範驗證Bean,默認false。

8、MethodValidationPostProcessor

Spring3.1開始支持,且只支持Hibernate Validator 4.2及更高版本,從Spring 3.2起可能將採取自動檢測Bean Validation 1.1兼容的提供商且自動註冊(Bean Validation 1.1 (JSR-349)正處於草案階段,它將提供方法級別的驗證,提供對方法級別的驗證),目前默認不自動註冊。

Bean Validation 1.1草案請參考http://jcp.org/en/jsr/detail?id=349 http://beanvalidation.org/。

提供對方法參數/方法返回值的進行驗證(即前置條件/後置條件的支持),通過JSR-303註解驗證,使用方式如:

public @NotNull Object myValidMethod(@NotNull String arg1, @Max(10) int arg2)

默認只對@org.springframework.validation.annotation.Validated註解的Bean進行驗證,我們可以修改validatedAnnotationType為其他註解類型來支持其他註解驗證。而且目前只支持Hibernate Validator實現,在未來版本可能支持其他實現。

有了這東西之後我們就不需要在進行如Assert.assertNotNull()這種前置條件/後置條件的判斷了。

9、ScheduledAnnotationBeanPostProcessor

當配置文件中有task:annotation-driven自動註冊或@EnableScheduling自動註冊。

提供對註解@Scheduled任務調度的支持。

postProcessAfterInitialization:通過查找Bean對象類上的@Scheduled註解來創建ScheduledMethodRunnable對象並註冊任務調度方法(僅返回值為void且方法是無形式參數的才可以)。

可參考Spring官方文檔的任務調度章節學習@Scheduled註解任務調度。

10、AsyncAnnotationBeanPostProcessor

當配置文件中有task:annotation-driven自動註冊或@EnableAsync自動註冊。

提供對@ Async和EJB3.1的@javax.ejb.Asynchronous註解的異步調用支持。

postProcessAfterInitialization:通過ProxyFactory創建目標對象的代理對象,默認使用AsyncAnnotationAdvisor(內部使用AsyncExecutionInterceptor 通過AsyncTaskExecutor(繼承TaskExecutor)通過submit提交異步任務)。

可參考Spring官方文檔的異步調用章節學習@Async註解異步調用。

11、ServletContextAwareProcessor

在使用Web容器時自動註冊。

類似於ApplicationContextAwareProcessor,當你的Bean 實現了ServletContextAware/ ServletConfigAware會自動調用回調方法注入ServletContext/ ServletConfig。

七、BeanPostProcessor如何註冊

1、如ApplicationContextAwareProcessor會在ApplicationContext容器啟動時自動註冊,而CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor會在當你使用context:annotation-config或context:component-scan配置時自動註冊。

2、只要將BeanPostProcessor註冊到容器中,Spring會在啟動時自動獲取並註冊。

八、BeanPostProcessor的執行順序

1、如果使用BeanFactory實現,非ApplicationContext實現,BeanPostProcessor執行順序就是添加順序。

2、如果使用的是AbstractApplicationContext(實現了ApplicationContext)的實現,則通過如下規則指定順序。

2.1、PriorityOrdered(繼承了Ordered),實現了該接口的BeanPostProcessor會在第一個順序註冊,標識高優先級順序,即比實現Ordered的具有更高的優先級;

2.2、Ordered,實現了該接口的BeanPostProcessor會第二個順序註冊;

int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;//最高優先級

int LOWEST_PRECEDENCE = Integer.MAX_VALUE;//最低優先級

即數字越小優先級越高,數字越大優先級越低,如0(高優先級)——1000(低優先級)

2.3、無序的,沒有實現Ordered/ PriorityOrdered的會在第三個順序註冊;

2.4、內部Bean後處理器,實現了MergedBeanDefinitionPostProcessor接口的是內部Bean PostProcessor,將在最後且無序註冊。

3、接下來我們看看內置的BeanPostProcessor執行順序

//1註冊實現了PriorityOrdered接口的BeanPostProcessor

//2註冊實現了Ordered接口的BeanPostProcessor

AbstractAutoProxyCreator 實現了Ordered,order = Ordered.LOWEST_PRECEDENCE

MethodValidationPostProcessor 實現了Ordered,LOWEST_PRECEDENCE

ScheduledAnnotationBeanPostProcessor 實現了Ordered,LOWEST_PRECEDENCE

AsyncAnnotationBeanPostProcessor 實現了Ordered,order = Ordered.LOWEST_PRECEDENCE

//3註冊無實現任何接口的BeanPostProcessor

BeanValidationPostProcessor 無序

ApplicationContextAwareProcessor 無序

ServletContextAwareProcessor 無序

//3 註冊實現了MergedBeanDefinitionPostProcessor接口的BeanPostProcessor,且按照實現了Ordered的順序進行註冊,沒有實現Ordered的默認為Ordered.LOWEST_PRECEDENCE。

PersistenceAnnotationBeanPostProcessor 實現了PriorityOrdered,Ordered.LOWEST_PRECEDENCE - 4

AutowiredAnnotationBeanPostProcessor 實現了PriorityOrdered,order = Ordered.LOWEST_PRECEDENCE - 2

RequiredAnnotationBeanPostProcessor 實現了PriorityOrdered,order = Ordered.LOWEST_PRECEDENCE - 1

CommonAnnotationBeanPostProcessor 實現了PriorityOrdered,Ordered.LOWEST_PRECEDENCE


從上到下順序執行,如果order相同則我們應該認為同序(誰先執行不確定,其執行順序根據註冊順序決定)。

九、完成Spring事務處理時自我調用的解決方案及一些實現方式的風險分析

場景請先參考請參考Spring事務處理時自我調用的解決方案及一些實現方式的風險中的3.3、通過BeanPostProcessor 在目標對象中注入代理對象。

分析:

Spring的Bean的生命週期(源碼分析)

問題出現在5和9處:

5、使用步驟1處註冊的SingletonFactory(ObjectFactory.getObject() 使用AnnotationAwareAspectJAutoProxyCreator的getEarlyBeanReference獲取循環引用Bean),因此此處將返回A目標對象的代理對象;


9、此處調用AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization,但發現之前調用過AnnotationAwareAspectJAutoProxyCreator的getEarlyBeanReference獲取代理對象,此處不再創建代理對象,而是直接返回目標對象,因此使用InjectBeanSelfProcessor不能注入代理對象;但此時的Spring容器中的A已經是代理對象了,因此我使用了從上下文重新獲取A代理對象的方式注入(context.getBean(beanName))。


此處的getEarlyBeanReference和postProcessAfterInitialization為什麼是二者選一的請參考之前介紹的AbstractAutoProxyCreator。


g事務處理時自我調用的解決方案及一些實現方式的風險分析

場景請先參考請參考Spring事務處理時自我調用的解決方案及一些實現方式的風險中的3.3、通過BeanPostProcessor 在目標對象中注入代理對象。

分析:

[外鏈圖片轉存中...(img-EHB5CPEj-1566178194724)]

問題出現在5和9處:

5、使用步驟1處註冊的SingletonFactory(ObjectFactory.getObject() 使用AnnotationAwareAspectJAutoProxyCreator的getEarlyBeanReference獲取循環引用Bean),因此此處將返回A目標對象的代理對象;


9、此處調用AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization,但發現之前調用過AnnotationAwareAspectJAutoProxyCreator的getEarlyBeanReference獲取代理對象,此處不再創建代理對象,而是直接返回目標對象,因此使用InjectBeanSelfProcessor不能注入代理對象;但此時的Spring容器中的A已經是代理對象了,因此我使用了從上下文重新獲取A代理對象的方式注入(context.getBean(beanName))。


此處的getEarlyBeanReference和postProcessAfterInitialization為什麼是二者選一的請參考之前介紹的AbstractAutoProxyCreator。


到此問題我們分析完畢,實際項目中的循環依賴應該儘量避免,這違反了“無環依賴原則”。


分享到:


相關文章: