spring-bean建立的生命週期與後置處理器的調用...

spring-bean建立的生命週期與後置處理器的調用點
1.第一次調用BeanPostProcess , InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation()方法.
try {
   // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
   // 第一次調用BeanPostProcess   InstantiationAwareBeanPostProcessor這個處理器的postProcessBeforeInstantiation()方法.
   // 若是一個對象,不想經過spring進行維護, 只是想放入spring容器當中, 就實現此接口, 反回一個你須要的對象出來
   // 這邊返回的對象不爲null時, 這個beanName的的建立也聚完成了, spring的後置處理器不會對此對象進行操做.
   // spring不推薦使用, 是spring提供內部添加對象時調用的.
   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);
} spring

// Make sure bean class is actually resolved at this point.
// 判斷是否有InstantiationAwareBeanPostProcessors的後置處理器.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   Class<?> targetType = determineTargetType(beanName, mbd);
   if (targetType != null) {
      // 若是調用postProcessBeforeInstantiation返回了一個對象, 那麼就直接執行後置處理器,此對象的實例化就完成.
      bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
      if (bean != null) {
         bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
      }
   }
} 緩存

通常來講 , 實現此接口返回的對象, 都是不須要通過spring幫咱們建立對象了 , 不須要spring進行管理了.  spring不推薦咱們使用, 而是交由spring內部本身調用的.
在spring-AOP有應用場景.
在咱們開啓AOP時.  添加 @EnableAspectJAutoProxy 註解.   基於spring的Import擴展  經過 ImportBeanDefinitionRegister, 幫咱們注入了一個後置處理器. mybatis

AnnotationAwareAspectJAutoProxyCreator.   此類是 InstantiationAwareBeanPostProcessor的子類, 從寫了 postProcessBeforeInstantiation()方法
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
   Object cacheKey = getCacheKey(beanClass, beanName); app

   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
      // 再次判斷beanClass中是否包含切面的註解 , 若是包含,保存到advisedBeans集合中,表明其實一個切面, 這樣在bean實例化以後,
      // 執行beanPostProcess的postProcessAfterInitialization方法時, 不會對切面進行加強.
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   } ide

   // Create proxy here if we have a custom TargetSource.
   // Suppresses unnecessary default instantiation of the target bean:
   // The TargetSource will handle target instances in a custom fashion.
   TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
   if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
         this.targetSourcedBeans.add(beanName);
      }
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   } post

   return null;
}
**  2. 第二次調用beanPostProcess, 來決定使用什麼構造方法來建立對象. SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法.
**// 第二次調用beanPostProcess , 用來決定是什麼哪一個構造方法建立對象.  SmartInstantiationAwareBeanPostProcessor 的determineCandidateConstructors()方法.
// 由後置處理器來肯定返回那些夠着方法, 若是拿到就使用這個構造方法實例化. spring爲何要這樣作呢?
// 咱們能夠經過反射直接拿到構造方法呀.
// beanPostProcess認爲若是你沒有沒有構造方法,或者你構造方法是默認的空參構造, 那麼此時返回的constructor= null.
// spring就認爲你不存在特殊的構造方法, 因此直接跳過調用空參構造建立對象, 若是有特殊的構造方法,那麼constructor != null,
// 就會使用你這個有參構造方法來建立對象.
// 可是若是有兩個構造方法時 , 而且你沒有指定primary的構造方法時, 也會返回null , 由於spring不知道你要使用哪一個構造方法,因此仍是讓你走空參構造建立對象.
// 簡單來講 , 若是有有且只有一個有參構造方法, 那麼就返回這個有參構造方法, 若是有多個構造方法 , 就使用空參構造建立.
// 可是若是在解析beanDefinotion給他添加了構造方法, 那麼就會使用到咱們添加的構造方法.
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 如何使用有參構造方法來建立對象呢?
// 有四個判斷條件.
// 1. 經過上方,後置處理器,找到了惟一的有參構造
// 2. BeanDefinition設置爲自動建立的模式  AUTOWIRE_CONSTRUCTOR
// 3. BeanDefinition咱們設置了ConstructorArgumentValues, 還記得mybatis嗎? 咱們掃描完BeanDefinition後,給BeanDefinition設置使用什麼構造參數和使用哪一個beanClass.
// 4. 調用singletonObject是,傳入的args就不爲空, 是有值的, 明確告訴你, 我須要構造方法建立.
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
      mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
   return autowireConstructor(beanName, mbd, ctors, args);
} ui

**   3. 第三次調用beanPostProcess, 此方法用來緩存bean中的註解信息. 此時對象已經建立出來, 可是spring尚未建立成功, 由於各類屬性還未添加.
**            MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition()方法. this

synchronized (mbd.postProcessingLock) {
   if (!mbd.postProcessed) {
      try {
         //第三次調用 beanPostProcess , MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition()方法
         applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      }
      catch (Throwable ex) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Post-processing of merged bean definition failed", ex);
      }
      mbd.postProcessed = true;
   }
} lua

  4. 第四次調用beanPostProcess, 用來提早暴露對象.spring認爲此時, 對象僅僅是new了出來, 可是沒有建立完成 , 對象走完spring的生命週期, 放入singletonObjects中, spring纔算對象建立完成. 此時會把bean保存到singleonFactories中. 至關於一箇中間集合, 若是對象在建立中, 由於引用其餘對象時 , getSingleton()方法 會先到singletonFactories中獲取, 若是獲取不到 , 再經過 creatBean()建立對象 , 用來解決spring的循環引用問題 .
            SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference() 方法.
if (earlySingletonExposure) {
   if (logger.isDebugEnabled()) {
      logger.debug("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
   }
   // 會把正在建立的bean保存到singletonFactories中
   // 第四次調用beanPostProcess , SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法, 用來解決循環依賴的
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
} debug

**5.第五次調用beanPostProcess, 用來判斷你的bean需不須要完成屬性填充 , 若是實現此接口 , 返回false , 那麼spring不會幫咱們填充屬性.
**            InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法.

// 第五次執行beanPostProcess , InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
         }
      }
   }
}

**   6. 第六次調用beanPostProcess,
**        AutowireAnnotationBeanPostProcessor 中的 postProcessProperrtyValues()方法.  主要使用來幫咱們完成屬性注入的 .
        CommonAnnotationBeanPostProcessor 中的  postProcessProperrtyValues()方法.  主要是用來處理@Resource的.**
// 判斷autowireMode是什麼類型, 默認實際上是 AUTOWIRE_BY_NO.
// 經過byName 或者 byType 拿到對應的屬性, 其中spring會進行過濾 , 賦值給pvs ,讓後置處理器去處理.
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
   // Add property values based on autowire by name if applicable.
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
      autowireByName(beanName, mbd, bw, newPvs);
   }
   // Add property values based on autowire by type if applicable.
   if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      autowireByType(beanName, mbd, bw, newPvs);
   }
   pvs = newPvs;
}

protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
   Set<String> result = new TreeSet<>();
   // 拿到咱們手動設置的屬性. 咱們拿到beanDefinition後能夠手動設置屬性.
   PropertyValues pvs = mbd.getPropertyValues();
   // 拿到class 的全部屬性.
   PropertyDescriptor[] pds = bw.getPropertyDescriptors();
   for (PropertyDescriptor pd : pds) {
      // 對全部的屬性進行過濾.  那些屬性是咱們想要的.
      // 1. 須要set方法.
      // 2. spring過濾接口, 不存在.
      // 3. pvs中不包含的pd ,  咱們手動添加給beanDefinition也須要過濾掉, 由於set方法確定是class本身的,而不是咱們手動添加的.
      // 4. 簡單類型的也忽略掉.
      if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
            !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
         result.add(pd.getName());
      }
   }
   return StringUtils.toStringArray(result);
}

if (hasInstAwareBpps) {

   //在這一步處理使用後置處理器來處理對象, 例如require , autowire 註解
   // 第六次調用beanPostProcess , InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法.
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
         if (pvs == null) {
            return;
         }
      }
   }
}

@Override
public PropertyValues postProcessPropertyValues(
      PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

   InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
   try {
      // 經過inject注入屬性.
      metadata.inject(bean, beanName, pvs);
   }
   catch (BeanCreationException ex) {
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
   }
   return pvs;
}

    @Override
   protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
      Field field = (Field) this.member;
      Object value;
      if (this.cached) {
         value = resolvedCachedArgument(beanName, this.cachedFieldValue);
      }
      else {
         DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
         desc.setContainingClass(bean.getClass());
         Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
         Assert.state(beanFactory != null, "No BeanFactory available");
         TypeConverter typeConverter = beanFactory.getTypeConverter();
         try {
            // 關鍵代碼 , 從spring的beanFactory中獲取對象
            value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
         }
         catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
         }
         synchronized (this) {
            if (!this.cached) {
               if (value != null || this.required) {
                  this.cachedFieldValue = desc;
                  registerDependentBeans(beanName, autowiredBeanNames);
                  if (autowiredBeanNames.size() == 1) {
                     String autowiredBeanName = autowiredBeanNames.iterator().next();
                     if (beanFactory.containsBean(autowiredBeanName) &&
                           beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                        this.cachedFieldValue = new ShortcutDependencyDescriptor(
                              desc, autowiredBeanName, field.getType());
                     }
                  }
               }
               else {
                  this.cachedFieldValue = null;
               }
               this.cached = true;
            }
         }
      }
      if (value != null) {
         ReflectionUtils.makeAccessible(field);
         field.set(bean, value);
      }
   }
}

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
      throws BeansException {

    // 調用到geiBean() , 而後經過getSingleton()獲取.
   return beanFactory.getBean(beanName);
}

**   7.  第七次調用beanPostProcess,   此時對象已經建立成功, 而且屬性填充完畢. 基本上一個bean對象已經建立完成.
**
if (mbd == null || !mbd.isSynthetic()) {
   // BeanPostProcess有兩個方法 ,這裏先執行  postProcessBeforeInitialization 方法.
   // 第七次執行BeanPostProcess , 真正執行的BeanPostProcess的postProcessBeforeInitialization()方法.
   // 以前執行的都是實現類中本身定義的擴展功能的方法.
   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
    //若是你的bean是ImportAware

   if (bean instanceof ImportAware) {
      ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
      AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName());
      if (importingClass != null) {
         ((ImportAware) bean).setImportMetadata(importingClass);
      }
   }
   return bean;
}

**  8. 第八次調用beanPostProcess, 建立對象的最後一步, aop的代理就是在此處建立.
**if (mbd == null || !mbd.isSynthetic()) {
   // 處理BeanPostProcess的另外一個方法 . postProcessAfterInitialization , aop就在此時作的.
   // 第八次執行beanPostProcess, 真正執行的beanPostProcess的postProcessAfterInitialization()方法.
   wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {
   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }
   // spring寫的代理工廠 , 工廠模式的使用
   ProxyFactory proxyFactory = new ProxyFactory();
   // 這隻proxyFactory工廠的屬性, 從這個類中, 由於此類繼承 ProxyConfig
   proxyFactory.copyFrom(this);

   // 判斷使用那種方式進行代理 , cglib 仍是 jdk
   // 由於在new ProxyFactory工廠時, 父類會建立 AopProxyFactory工廠,
   // 此類的createAopProxy(),中調用proxyTargetClass屬性, 若是是true,就使用cglib , spring默認是false.
   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }

   // 拿到咱們切面中的全部方法.
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);
   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
   return proxyFactory.getProxy(getProxyClassLoader());
}

以上就是spring掃描的咱們對應的類以後 , 經過beanDefinition建立對象的流程. 歡迎討論

相關文章
相關標籤/搜索