概念:

循环依赖其实就是对象循环引用,也就是两个或以上的Bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A;

Spring 中循环依赖场景有:

  1. 构造器的循环依赖(构造器注入)
  2. 成员属性的循环依赖(set注入)

对于多例 prototype 原型 Bean 的初始化过程中,不论是构造器参数循环依赖,还是通过set方法产生循环依赖,spring都是直接报错处理。

Spring的循环依赖的解决方式基于Java的引用传递,单例Bean使用构造器参数产生的循环依赖问题,构造器是在获得引用之前的,无法产生实例对象,也无法获得引用对象,所以无法解决。

Spring解决的循环依赖类型:

spring的循环依赖的理论基于Java的引用传递,当获得对象的引用时,对象的属性是可以延后设置的。

spring能解决的循环依赖的场景是单例下通过set方法或者注解方法上注入依赖对象,其实是通过提前暴露一个ObjectFactory对象来完成的。

循环依赖涉及到的三级缓存:

一级缓存(singletonObjects ):单例池,创建完成的单例Bean放在这里。

二级缓存(earlySingletonObjects):存放实例化,未完成初始化的单例对象(未完成属性注入的对象),也是用来解决性能问题。

三级缓存(singletonFactories):存放ObjectFactory对象,存放的是创建Bean的原始工厂对象,也是用来解决aop的问题。

后两个缓存只是创建Bean的时候,用来临时存放,创建完成就清掉了。

实际上使用二级缓存就能够实现循环依赖的解决,将二级缓存用来存放早期单例对象(半成品),然后一样的走生命周期的流程。

使用第三级缓存的目的:通过ObjectFactory对象工厂利用aop处理生成代理对象(其中的getEarlyBeanReference方法在实现类AbstractAutoProxyCreator中和postProcessAfterInitialization非常相似)

Demo流程图:

springboot 各模块循环依赖 Annotation processing is not supported for module spring循环依赖场景_java