spring小結---bean循環依賴

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
      isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
   if (logger.isDebugEnabled()) {
      logger.debug("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
   }
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
   populateBean(beanName, mbd, instanceWrapper);
   exposedObject = initializeBean(beanName, exposedObject, mbd);
}
/**
 * Add the given singleton factory for building the specified singleton
 * if necessary.
 * <p>To be called for eager registration of singletons, e.g. to be able to
 * resolve circular references.
 * @param beanName the name of the bean
 * @param singletonFactory the factory for the singleton object
 */
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);
      }
   }
}//bean: 剛剛創建的bean,不存在任何集合中

earlySingletonObjects表示過渡性對象map,已經new出來,但屬性沒填充

singletonObjects:表示已經創建好的對象map

繼續

try {  //

//設置填充屬性
populateBean(beanName, mbd, instanceWrapper);

//執行後置處理器,aop就是這裏執行的
exposedObject = initializeBean(beanName, exposedObject, mbd);
}

其中populateBean也是通過後置處理器完成屬性填充
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   if (bw == null) {
      if (mbd.hasPropertyValues()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      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.
   boolean continueWithPropertyPopulation = true;
     //其中class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
    //  implements InstantiationAwareBeanPostProcess//處理@resource,@PostConstruct @Predestroy

   //還有AutowiredAnnotationBeanPostProcessor

//AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements //MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {//處理@autowire

   
   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;
   }
    //spring同樣像給構造方法參數一樣可以給bean屬性設置默認值
   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

      // Add property values based on autowire by name if applicable.
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }

      // Add property values based on autowire by type if applicable.
      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);

   if (hasInstAwareBpps || needsDepCheck) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      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;
               }
            }
         }
      }
      if (needsDepCheck) {
         checkDependencies(beanName, mbd, filteredPds, pvs);
      }
   }

   if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

以下面的2個類相互引用爲例

@Component("cirdao")
public class CircusLmqDao {

    @Autowired
    CircusLmqService circusLmqService;

    public void updatequerydao()
    {
        System.out.println("updatequerydao .............");
    }
@Component("cirservice")
public class CircusLmqService {

  @Autowired
  CircusLmqDao circusLmqDao;

    public void updatequery()
    {
        System.out.println("updatequery .............");
    }


}

因爲要設置屬性,所以下面斷點如下

進入

此時只是bean,還沒給屬性賦值,比如circuslmqservice=null,

繼續往下,其中AutowiredAnnotationBeanPostProcessor

for (BeanPostProcessor bp : getBeanPostProcessors()) {
   if (bp instanceof InstantiationAwareBeanPostProcessor) {
      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
      pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
      if (pvs == null) {
         return;

其中AutowiredAnnotationBeanPostProcessor會在上面起作用

進去

往下

接着進入

進入element.inject


field可以看出

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 {
            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);
      }
   }
}

進入

進去resolveDependency

public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

   descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
   if (Optional.class == descriptor.getDependencyType()) {
      return createOptionalDependency(descriptor, requestingBeanName);
   }
   else if (ObjectFactory.class == descriptor.getDependencyType() ||
         ObjectProvider.class == descriptor.getDependencyType()) {
      return new DependencyObjectProvider(descriptor, requestingBeanName);
   }
   else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
      return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
   }
   else {
      Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
            descriptor, requestingBeanName);
      if (result == null) {
         result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
      }
      return result;
   }
}

對於其中的 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);

進去後

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

   InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
   try {
      Object shortcut = descriptor.resolveShortcut(this);
      if (shortcut != null) {
         return shortcut;
      }

      Class<?> type = descriptor.getDependencyType();
      Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
      if (value != null) {
         if (value instanceof String) {
            String strVal = resolveEmbeddedValue((String) value);
            BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
            value = evaluateBeanDefinitionString(strVal, bd);
         }
         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
         return (descriptor.getField() != null ?
               converter.convertIfNecessary(value, type, descriptor.getField()) :
               converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
      }

      Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
      if (multipleBeans != null) {
         return multipleBeans;
      }

      Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
      if (matchingBeans.isEmpty()) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         return null;
      }

      String autowiredBeanName;
      Object instanceCandidate;

      if (matchingBeans.size() > 1) {
         autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
         if (autowiredBeanName == null) {
            if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
               return descriptor.resolveNotUnique(type, matchingBeans);
            }
            else {
               // In case of an optional Collection/Map, silently ignore a non-unique case:
               // possibly it was meant to be an empty collection of multiple regular beans
               // (before 4.3 in particular when we didn't even look for collection beans).
               return null;
            }
         }
         instanceCandidate = matchingBeans.get(autowiredBeanName);
      }
      else {
         // We have exactly one match.
         Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
         autowiredBeanName = entry.getKey();
         instanceCandidate = entry.getValue();
      }

      if (autowiredBeanNames != null) {
         autowiredBeanNames.add(autowiredBeanName);
      }
      if (instanceCandidate instanceof Class) {
         instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
      }
      Object result = instanceCandidate;
      if (result instanceof NullBean) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         result = null;
      }
      if (!ClassUtils.isAssignableValue(type, result)) {
         throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
      }
      return result;
   }
   finally {
      ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
   }
}

看下中間過程,其中依賴的屬性的lmqservice還沒創建,所以val==null

繼續看下過程

if (instanceCandidate instanceof Class) //很關鍵

{ instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); }

進去此方法(此時lmqserice還沒實例化,裏面是如何解決·)

執行到此,此時的beanname爲lmqservice也就是cirdao的屬性,查看下此時的beanfactory的objects集合

如圖示,在正在創建cirdao時,首先被放在singletonFactories中,而此時singletonobjects既沒cirdao實例也沒lmqservice實例,

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

   return beanFactory.getBean(beanName);
}

進去return beanFactory.getBean(beanName);

繼續進入

此時的getsingle肯定是null,第一次調用,細看下

Object sharedInstance = getSingleton(beanName);如下圖,傳了個參數allowEarlyReference=true//允許早期暴露

對於此時是正在創建cirdao, 

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//對於criservice不成立,直接返回,但此時
      synchronized (this.singletonObjects) {
         singletonObject = this.earlySingletonObjects.get(beanName);
         if (singletonObject == null && allowEarlyReference) {
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();
               this.earlySingletonObjects.put(beanName, singletonObject);
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}

會進入cirservice的實例化

同樣進入和cirdao的實例化流程,此時beanname=cirservice

繼續

繼續

後面同樣進入cirservice的populateBean()過程,

同樣適用wrapper的object的屬性circusLmqdap目前還是null

繼續,直到後置處理器設置屬性,autowire處理時,

PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
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;
         }
      }

進去;

和cirdao的類似

進去

value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);

進去

進去

doResolveDependency()

如下圖

進去(和之前創建cirsdao類似)

if (instanceCandidate instanceof Class) {
   instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}

接着進去dogetbean(cirsdao)//此時由於之前已經創建cirsdap實例雖然未設置完屬性

所以下面的getsingletonobejct()不爲空,可以看一下

final String beanName = transformedBeanName(name);
Object bean;

// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {

........................

繼續

執行完上面的就把第一次半成品的cirsdao從singfactory拿出來放到earlysinglletonobjects中,

其中cirsdao實例(只是創建,還沒屬性)是之前創建完放到singfactory中的,如下

//if (earlySingletonExposure) {
 //  if (logger.isDebugEnabled()) {
 //     logger.debug("Eagerly caching bean '" + beanName +
  //          "' to allow for resolving potential circular references");
  // }
  // addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
//}

removr後

factory只剩一個了.

但此時正在創建的仍是2個,

當拿到cirdao後,返回,給cirslmqservice設置屬性,

try {
   value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
繼續回退,看下調用棧,

繼續走

field.set(bean, value);如下

這裏由於先初始化cirdao,但cirdao又依賴cirlmqservice,所以先把cirslmqserivce初始化並設置好,再反過來設置cirdao,後面的cirdao也會有個field.set(), //可以反覆看下調用棧

看下回退調用棧,再看下第一次的inject

下面仍會有filed.set()

          value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
      }
      catch (BeansException ex) {
         throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
      }
.............................
         }
      }
   }
   if (value != null) {
      ReflectionUtils.makeAccessible(field);
      field.set(bean, value);
   }
}

等過程回到創建半個cirdao(尚未設置屬性)後,由於之前依賴的cirserve已經初始化並設置完屬性依賴,會返回完整的crslmqservice bean對象

然後也開始fiedl.set,如下圖,

查看此時的singleobjects

因爲cirservice初始化並設置好屬性,所以添加到了singleobjects,在這裏需要觀察下在哪個位置添加的

而cirdao還沒來得及加到,需要看下

繼續執行,也就是按步執行,回到最初調用起點,(本次函數調用棧較多,由於本次實驗循環依賴,執行過程一樣,方法棧重複了2次)

根據調用棧,一步步來,發現在上方面的方法中cirdao已添加到singletonobjects,由於crisservice之前添加過程一樣,不再贅述。

至此循環依賴完成,

綜上earlysinglepbjects只是add,put, 獲取是在singletonfactorys拿到的,總結就是先把半成品x(以實例化但沒設置屬性的bean)f放在全局的singletonfactorys,然後類似遞歸處理依賴的對象y,由於x和y相互依賴,之前的半成品x已存在,可以順利完成y的初始化(包括field.set),返回上一級繼續完成x的field.set,完成屬性設置,添加到singletonobjects()

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章