什么是循环依赖
循环依赖其实就是循环引⽤,也就是两个或者两个以上的 Bean 互相持有对⽅,最终形成闭环。⽐如A
依赖于B,B依赖于C,C⼜依赖于A。
注意,这⾥不是函数的循环调⽤,是对象的相互依赖关系。循环调⽤其实就是⼀个死循环,除⾮有终结条件。
Spring中循环依赖场景有:
- 构造器的循环依赖(构造器注⼊)
- Field 属性的循环依赖(set注⼊)
其中,构造器的循环依赖问题⽆法解决,只能拋出BeanCurrentlyInCreationException 异常,在解决属性循环依赖时,spring采⽤的是提前暴露对象的⽅法。
解决办法理论说明
Spring使用的方法,可以形象的比喻为三级缓存机制。
比如,A依赖B,B也依赖于A时,Spring的创建过程大概如下
- 先实例化A,执行构造函数,A的属性还没有处理完成,然后将对象A放入三级缓存
- 接着处理A的属性,发现A依赖于B,这时候要开始创建B
- 实例化B完成以后,开始处理B的属性,发现B依赖于A,此时就先去三级缓存中找A
- 找到A之后,将A转移到二级缓存
- 这是对象B已经完成了创建,被放入一级缓存
- 接着A继续设置属性,此时一级有完整的B,A的创建也可以完成。