Spring是如何解决循环依赖(引用)的?

首先什么是循环依赖,比如A->B->A,正常我们普通的类怎么解决呢,就是先  new A(),new B() ,然后再 setB,setA ,也比较好解决。

那么大家为什么会经常提到spring循环依赖呢,我认为主要有两个原因:

  1. spring的bean是一个一个加载的,A创建的过程中,发现依赖B,B还没创建,就会去先创建B
  2. spring的bean有一个较复杂的生命周期,它的bean常常需要被生成代理

那spring是如何解决这个循环依赖问题的呢?

spring的核心思想同样是:先实例化,后设置属性。它内部维护了三个map,就是网上常说的三级缓存

一个是 singletonObjects  map ,也就是我们说的单例池,它存放的是已经完成实例化的完成的bean;

一个是 singletonFactories  map,二级缓存,它是解决循环依赖的关键,也就是存放未完全创建的对象工厂ObjectFactory,它持有原对象的引用;

一个是 earlySingletonObjects  map,三级缓存,它是存放经过ObjectFactory.getObject,生成的早期单例对象存在这个map中,这里面的对象可能是个代理类。

 singletonFactories  、 earlySingletonObjects  中的对象都还不是完整的bean,都还没有进行属性的注入,以及初始化过程。

注:很多文章会称 singletonFactories 为三级缓存, earlySingletonObjects 为二级缓存,这里其实没有谁对谁错,只是个叫法,不用纠结。

说明:原型(Prototype)的场景、通过构造方法进行依赖注入,这两种情况循环依赖都没有解决

spring的解决循环依赖的大概过程

 创建A,先把A通过构造方法反射实例化得到一个空的对象,然后根据是否单例,是否允许循环引用,如果是的话,包装一个 ObjectFactory 对象,加到 singletonFactories  map中,然后进行A的属性设置,这时候发现A的属性B还没创建,转而先去创建B,同样的,先把B加到 singletonFactories  map中,设置B的属性的时候,发现A还没创建,又转而去创建A,此时A已经在 singletonFactories ,然后调用A的ObjectFactory中的getObject方法,获取A的早期引用(生成的可能是个代理对象,此时A还没实例完全,属性还没设置),然后会把A转移到earlySingletonObjects map中(),接着继续执行B的属性填充等初始化过程,B的创建过程完成,将B加到单例池中。B创建完之后,回到A的创建过程,进行属性填充,将B设置到A上,完成A的初始化过程,完后将A从earlySingletonObjects中取出,加到singletonObjects 单例池中。至此,循环依赖过程结束后。

 为什么第二级缓存要使用ObjectFactory?

为了这个bean能够被一些beanPostProcessor处理,使其能够创建为代理对象。

三级缓存earlySingletonObjects 的作用是什么?

存储ObjectFactory.getObject()之后生成的半成品对象(这个对象只是原本的实例化,或者代理对象,没有经历过属性注入与初始化过程),用于保存真实的对象引用,因为真正要放到单例池中的对象可能是个代理对象

 postProcessAfterInitialization也可以生成代理,ObjectFactory.getObject()生成代理后,再执行postProcessAfterInitialization,岂不是会执行两遍生成代理流程?

debug发现,ObjectFactory.getObject()返回的确实是代理对象(如果需要的话),后续在执行postProcessAfterInitialization的时候,会有个earlyProxyReferences的判断,直接返回原对象,在后面流程中,会从earlySingletonObjects 中取代理后的对象,放到单例池中。

说明,debug发现

  1. B只会经过singletonFactoriessingletonObjects ,不经过earlySingletonObjects
  2. 如果A需要生成代理对象,那生成的代理对象中的属性值为null,如:A->B->$proxyA->b=null,单例池中存放的是代理后的A
  3. 如果A不需要生成代理对象,那么关系就是 A->B->A->B....,形成循环依赖

 关键源码:

注:只列出与循环依赖相关的关键代码

// org.springframework.beans.factory.support.AbstractBeanFactory

protected <T> T doGetBean(
            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
            throws BeansException {
  
      // 获取单例bean,首次进来为null
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            ...
        } else {
      ...
      // Create bean instance.
                if (mbd.isSingleton()) {
          // 获取单例对象,没有则执行创建,第二个参数为ObjectFactory
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
              // 创建bean
                            return createBean(beanName, mbd, args);
                        } catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                }
    }
}
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
...
  if (instanceWrapper == null) {
        // 实例化bean
            instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
...
  // 是否单例,是否可以循环引用,是否是正在创建中的单例对象
  boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
      // 提前暴露工厂对象,将ObjectFactory添加到singletonFactories中
     // getEarlyBeanReference返回的对象会经过一些BeanPostProcessor的处理,可能生成对应的代理对象,如果不需要代理,则基本都是原对象
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }
  
  ...
  // 属性注入,如果发现有依赖的bean,并且未创建,回去先创建依赖的bean
  populateBean(beanName, mbd, instanceWrapper);
  // 初始化回调流程
    exposedObject = initializeBean(beanName, exposedObject, mbd);
  
  ...
  if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) 
          // 这个地方会把原对象,替换成代理对象
                    exposedObject = earlySingletonReference;
                }
      }
  }
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

// 上面的getEarlyBeanReference方法中调用的
@Override
    public Object getEarlyBeanReference(Object bean, String beanName) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        this.earlyProxyReferences.put(cacheKey, bean);
        return wrapIfNecessary(bean, beanName, cacheKey);
    }

// bean生命周期中initializeBean方法中的流程,一般AOP代理也在这边生成
@Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // 代理对象的话,这边不会进入if  
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
  
  /**(一级缓存)已经完成加载的单例缓存.*/
  private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
  /**(三级缓存)早期的单例对象缓存集合. 存储二级缓存加工过的对象,此时该Bean还未构建完成 */
  private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
  /**(二级缓存)单例的工厂Bean缓存集合. */
  private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

  public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    ...
      singletonObject = singletonFactory.getObject();
      newSingleton = true;
    ...
      if (newSingleton) {
        // 添加到单例池中
        addSingleton(beanName, singletonObject);
      }
  }

  // 加到二级缓存
  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);
        }
      }
   }
  
  ......
  // 注:高版本的spring,这个方法会稍有不同(有double check的逻辑),思路是一样的
  protected Object getSingleton(String beanName, boolean allowEarlyReference) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
          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;
  }
}
原文地址:https://www.cnblogs.com/dong320/p/14529731.html