Spring中的循环引用
循环依赖:循环依赖其实就是循环引用,也就是两个或两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A
循环依赖在spring中是允许存在,spring框架依据三级缓存已经解决了大部分的循环依赖
- ①一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象
- ②二级缓存:缓存早期的bean对象(生命周期还没走完)
- ③三级缓存:缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的
解决流程
- 第一,先实例A对象,同时会创建ObjectFactory对象存入三级缓存singletonFactories
- 第二,A在初始化的时候需要B对象,这个走B的创建的逻辑
- 第三,B实例化完成,也会创建ObjectFactory对象存入三级缓存singletonFactories
- 第四,B需要注入A,通过三级缓存中获取ObjectFactory来生成一个A的对象同时存入二级缓存,这个是有两种情况,一个是可能是A的普通对象,另外一个是A的代理对象,都可以让ObjectFactory来生产对应的对象,这也是三级缓存的关键
- 第五,B通过从通过二级缓存earlySingletonObjects 获得到A的对象后可以正常注入,B创建成功,存入一级缓存singletonObjects
- 第六,回到A对象初始化,因为B对象已经创建完成,则可以直接注入B,A创建成功存入一次缓存singletonObjects
- 第七,二级缓存中的临时对象A清除
构造方法出现了循环依赖
由于bean的生命周期中构造函数是第一个执行的,spring框架并不能解决构造函数的的依赖注入,可以使用@Lazy懒加载,什么时候需要对象再进行bean对象的创建