spring 单实例循环依赖之源码解析(七)

spring依赖注入的主干核心源码我们上篇已经分析过了,今天我们重点解析 spring 单实例循环依赖问题,为啥强调单实例呢?因为在spring 中 多实例和有参构造函数上带注解的是无法循环依赖的(这块内容以后也会细讲)。首先说一下单实例循环依赖整体流程,然后再去分析源码。

1、假如有m、n两个类相互依赖注入;

package com.nandao.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TestM {

    public TestM() {
    }

    @Autowired
    private TestN testN;
}
package com.nandao.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class TestN {

    public TestN() {
    }

    @Autowired
    private TestM testM;
}

2、我们先实例化 M 类,看源码,这里我只把方法里的核心点列出来,只关注重点代码(无用的 暂时删),从

AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory  的doGetBean 方法开始
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

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

      //先从缓存中拿实例,首次创建不会走这里,第二次会(getBean)走这里,一会会讲到这。
   Object sharedInstance = getSingleton(beanName);
   //如果缓存里面能拿到实例
   if (sharedInstance != null && args == null) {
      if (logger.isTraceEnabled()) {
         if (isSingletonCurrentlyInCreation(beanName)) {
            logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                  "' that is not fully initialized yet - a consequence of a circular reference");
         }
         else {
            logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
         }
      }
      //改方法是FactoryBean接口的调用入口
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }
   else {
      //如果singletonObjects缓存里面没有,则走下来
      //如果是scope 是Prototype的,校验是否有出现循环依赖,如果有则直接报错
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // Check if bean definition exists in this factory.
      BeanFactory parentBeanFactory = getParentBeanFactory();
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         // Not found -> check parent.
         String nameToLookup = originalBeanName(name);
         if (parentBeanFactory instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                  nameToLookup, requiredType, args, typeCheckOnly);
         }
         else if (args != null) {
            // Delegation to parent with explicit args.
            return (T) parentBeanFactory.getBean(nameToLookup, args);
         }
         else if (requiredType != null) {
            // No args -> delegate to standard getBean method.
            return parentBeanFactory.getBean(nameToLookup, requiredType);
         }
         else {
            return (T) parentBeanFactory.getBean(nameToLookup);
         }
      }

      if (!typeCheckOnly) {
         markBeanAsCreated(beanName);
      }

      try {
         //父子两个BeanDefinition合并
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);

         //获取依赖对象属性,依赖对象要先实例化
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            for (String dep : dependsOn) {
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               registerDependentBean(dep, beanName);
               try {
                  //实例化
                  getBean(dep);
            }
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }

         //重点看,创建单例实例,大部分是都单例的情况
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  return createBean(beanName, mbd, args);//核心方法进入-->
               }
               catch (BeansException ex) {
                  // Explicitly remove instance from singleton cache: It might have been put there
                  // eagerly by the creation process, to allow for circular reference resolution.
                  // Also remove any beans that received a temporary reference to the bean.
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            //改方法是FactoryBean接口的调用入口
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }

//删除部分
   return (T) bean;
}

2、进入   AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory

中的 createBean(beanName, mbd, args)方法

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   if (logger.isTraceEnabled()) {
      logger.trace("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;

   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

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

   try {
      //主要看这个方法 ,点击进入-->
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
  
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      //创建实例,无参构造方法实例化 
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   final Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            //CommonAnnotationBeanPostProcessor  支持了@PostConstruct,@PreDestroy,@Resource注解
            //AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解
            //BeanPostProcessor接口的典型运用,这里要理解这个接口
            //对类中注解的装配过程
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true;
      }
   }

   // 单例bean 是否可以 提前暴露,这里是循环依赖的切入点
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {//如果提前暴露
      if (logger.isTraceEnabled()) {
         logger.trace("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 {
      // M 类依赖注入的核心方法, 点击进入-->
      populateBean(beanName, mbd, instanceWrapper);

      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
   catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
         throw (BeanCreationException) ex;
      }
      else {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
   }

   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<>(dependentBeans.length);
            for (String dependentBean : dependentBeans) {
               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                  actualDependentBeans.add(dependentBean);
               }
            }
           
//删除部分
   // Register bean as disposable.
   try {
      //注册bean销毁时的类DisposableBeanAdapter
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
 //删除部分

   return exposedObject;
}

3、来到  DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry 类的 

addSingletonFactory 方法
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);
      }
   }
}

4、点击  populateBean(beanName, mbd, instanceWrapper); 进入

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

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

               //是否需要DI,依赖注入
               continueWithPropertyPopulation = false;
               break;
            }
         }
      }
   }

   if (!continueWithPropertyPopulation) {
      return;
   }

   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // M 类中 根据有 autowire的名称寻找属性,进行依赖注入,这里特指 N 类,点击进入-->
      if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }
      // Add property values based on autowire by type if applicable.
      if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

   PropertyDescriptor[] filteredPds = null;

 
   if (hasInstAwareBpps) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            //依赖注入过程,@Autowired的支持
            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               if (filteredPds == null) {
                  filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
               }

               //老版本还是用这个完成依赖注入过程,@Autowired的支持
               pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvsToUse == null) {
                  return;
               }
            }
            pvs = pvsToUse;
         }
      }
   }
 
}

点击  autowireByName(beanName, mbd, bw, newPvs) 进入

protected void autowireByName(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      if (containsBean(propertyName)) {
//看这里,propertyName 参数是 N 类的类名,进行getBean---doGetBean 实例化,这时开始N类的实例化,开始循环,同时也是循环依赖的
//入口,这时回到了最初(最上面的)的doGetBean方法,开始实例化N,N类实例化后也进行设置了三级缓存;
         Object bean = getBean(propertyName);
         pvs.add(propertyName, bean);
         registerDependentBean(propertyName, beanName);
         if (logger.isTraceEnabled()) {
            logger.trace("Added autowiring by name from bean name '" + beanName +
                  "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
         }
      }
      else {
         if (logger.isTraceEnabled()) {
            logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                  "' by name: no matching bean found");
         }
      }
   }
}

重点:当 N 类走到需要进行依赖注入的M类时,也是走到这个方法,驱动M类 进行实例化;当M 类进行实例化时,先从缓存中取!!!,如下:

//从缓存中拿实例,我们上面已经重点提到。
Object sharedInstance = getSingleton(beanName);//点击进入--->

5、进入 DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry 类的 

@Override
@Nullable
public Object getSingleton(String beanName) {
   return getSingleton(beanName, true);//进行点击-->
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   //根据beanName从缓存中拿实例
   //先从一级缓存拿
   Object singletonObject = this.singletonObjects.get(beanName);
   //如果bean还正在创建,还没创建完成,其实就是堆内存有了,属性还没有DI依赖注入
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         //从二级缓存中拿
         singletonObject = this.earlySingletonObjects.get(beanName);

         //如果还拿不到,并且允许bean提前暴露
         if (singletonObject == null && allowEarlyReference) {
            //从三级缓存中拿到对象工厂
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               //从工厂中拿到对象
               singletonObject = singletonFactory.getObject();
               //升级到二级缓存
               System.out.println("======get instance from 3 level cache->beanName->" + beanName + "->value->" + singletonObject );
               this.earlySingletonObjects.put(beanName, singletonObject);
               //删除三级缓存
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}

重点:这时候N 类拿到了 M 提前暴露的实例类,N类就实例化完成了,N 类的实例化是由 M 类实例化中 A 属性的依赖注入触发 的 getBean 操作进行的,现在 N 已经实例化,所以 M  类中 N  属性就可以完成依赖注 入了,这时候 M 类中 N 属性已经有值了。这时候,N 类中 M 属性指向的就是 M 类实例堆空间,所以这时候 N  类 中 M 属性也会有值了。此时此刻,依赖注入正式完成!!!

今天解析到这里,有不懂的地方,可以留言!!!下期更精彩!!!

猜你喜欢

转载自blog.csdn.net/nandao158/article/details/105778478