【知识积累】Spring循环依赖问题怎么解决?

1、什么是循环依赖?

即:A依赖B,B依赖A,构成一个闭环。

2、循环依赖的场景

2.1、构造器依赖注入

spring无法解决

2.2、setter方法依赖注入

spring的单例bean的创建分为三步:

  • createBeanInstance:实例化
    • E:/Repository/org/springframework/spring-beans/5.1.15.RELEASE/spring-beans-5.1.15.RELEASE.jar!/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.class:343
  • this.populateBean:填充属性
    • E:/Repository/org/springframework/spring-beans/5.1.15.RELEASE/spring-beans-5.1.15.RELEASE.jar!/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.class:378
  • this.initializeBean:初始化
    • E:/Repository/org/springframework/spring-beans/5.1.15.RELEASE/spring-beans-5.1.15.RELEASE.jar!/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.class:379

循环依赖的问题主要发生在第一步和第二步,spring的单例bean是放入cache里面的,有且只有一个对象,为了解决循环依赖的问题,使用了三级缓存。

先看看源码:

【知识积累】Spring循环依赖问题怎么解决?_第1张图片

【知识积累】Spring循环依赖问题怎么解决?_第2张图片

【知识积累】Spring循环依赖问题怎么解决?_第3张图片

当我们创建A的时候,首先完成第一步实例化,然后将对象缓存进singletonFactories(三级),然后开始第二步填充属性,发现B没有被创建,然后开始创建B,先实例化,后填充属性,发现依赖A,然后执行上面的代码,一级一级缓存去查找,因为A提前通过ObjectFactory暴露了,所以拿到了还没有完全初始化完毕的A,并将没有完全初始化的A放入earlySingletonObjects(二级),这样B就完成了创建,并且将自己缓存到了singletonObjects(一级),这样A也创建成功了,最后将自己放入singletonObjects(一级)。

对于“singleton”作用域Bean,可以通过setAllowCircularReferences(false);来禁用循环引用

3、对于prototype作用域的bean

prototype作用域的bean无法解决,因为对于prototype作用域的bean不进行缓存,因此无法提前暴露一个创建中的bean。

 

你可能感兴趣的:(Spring)