springbean的生命週期(上)

本篇主要介紹springbean的生命週期第一部分,每一部分的分層是按照BeanPostProcessor後置處理器來完成的。

本篇完成內容爲

1.將需要進行aop代理的對象存放到集合中(已存在對象AppConfig.class 通過BeanFactoryPostProcessor 完成CGLIB增強)

   BeanPostProcessor#AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation();

2.推斷構造方法初始化對象(spring-ioc-推斷構造函數-手動裝配spring-ioc-推斷構造函數-自動裝配

   BeanPostProcessor#AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors();

3.合併beanDefinition(後面補,前面BeanFactoryPostProcessor方法中已經做過一些合併處理)

4.處理循環依賴(spring-ioc-循環依賴)

   BeanPostProcessor#AnnotationAwareAspectJAutoProxyCreator#getEarlyBeanReference(); 

此篇內容先引入前篇文章的兩張圖

如圖,此時bean後置處理器有6個,我們現在在測試環境的配置類中加上開啓aop的支持

@EnableAspectJAutoProxy就會多出一個來AnnotationAwareAspectJAutoProxyCreator

老樣子還是看一看BeanPostProcessor繼承圖實現類有很多......

 

個人覺得springbean的生命週期就是從創建bean開始的AbstractAutowireCapableBeanFactory#createBean()
所以我們有了 BeanPostProcessor 後置處理器的第一步解決了將需要進行代理的對象存到了一個集合中,下面來看代碼

BeanPostProcessor#AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation();

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
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.
      // 判斷是否爲一個合成的bd(默認false) &&  默認true
      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;
}
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;
}
AnnotationAwareAspectJAutoProxyCreator
--postProcessBeforeInstantiation -- advisedBeans.put(object,false)--處理後返回null
advisedBeans 已經有appconfig 呢,bean工廠後置處理器已代理
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
   Object cacheKey = getCacheKey(beanClass, beanName);

   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
      // 判斷這個對象是否是一個代理對象,已經存在AppConfig.class
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   }

//有刪減

}

protected boolean isInfrastructureClass(Class<?> beanClass) {
   return (super.isInfrastructureClass(beanClass) ||
         (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
public boolean isAspect(Class<?> clazz) {
   return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}

//返回true 包含註解@Aspect
private boolean hasAspectAnnotation(Class<?> clazz) {
   return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
//返回false 獲取到屬性值 BServiceBo bServiceBo getName不包含AJC_MAGIC
private boolean compiledByAjc(Class<?> clazz) {
   for (Field field : clazz.getDeclaredFields()) {
      if (field.getName().startsWith(AJC_MAGIC)) {
         return true;
      }
   }
   return false;
}

處理循環依賴(可參考 spring-ioc-循環依賴)

如果配置類沒有加@EnableAspectJAutoProxy 註解 那麼這個 後置處理器不會有,getEarlyBeanReference() 這段代碼也直接返回空,如果加了 就會 在這個map中 earlyProxyReferences.put(cacheKey, bean)

   BeanPostProcessor#AnnotationAwareAspectJAutoProxyCreator#getEarlyBeanReference(); 

構造方法之所以不能解決循環依賴問題是因爲後置處理器先處理了構造方法初始化纔來解決循環依賴,順序不同。

可參考重新繪製的流程圖

 

發佈了40 篇原創文章 · 獲贊 9 · 訪問量 4148
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章