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()

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值