spring解决循环依赖
有如下A、B、C三个类。
public class A{ public A(B b){} }
public class B{ public B (C c){} }
public class C{ public C(A a){} }
这是一个典型的三方循环依赖的例子,Spring 是通过三级缓存机制来完成对象的初始化的。
具体的初始化过程如下:
- 创建 Bean A 时,发现其构造器需要 Bean B 的实例,但是 Bean B 还未初始化,所以:
- 将 Bean B 的实例工厂添加到三级缓存 SingletonFactories 中;
- Bean A 实例添加到二级缓存 EarlySingletonObjects 中;
此时缓存状态:
SingletonFactories = {B 工厂}
EarlySingletonObjects = {A 实例}
- 创建 Bean B 时,发现其构造器需要 Bean C 的实例,但是 Bean C 还未初始化,所以:
- 将 Bean C 的实例工厂也添加到三级缓存 SingletonFactories 中;
- Bean B 实例也添加到二级缓存 EarlySingletonObjects 中;
此时缓存状态:
SingletonFactories = {B 工厂, C 工厂}
EarlySingletonObjects = {A 实例, B 实例}
- 创建 Bean C 时,发现其构造器需要 Bean A 的实例,此时 Bean A 已在二级缓存中,所以:
- 从 EarlySingletonObjects 中获取 Bean A 实例;
- 将 Bean C 实例添加到 EarlySingletonObjects 中;
此时缓存状态:
SingletonFactories = {B 工厂, C 工厂}
EarlySingletonObjects = {A 实例, B 实例, C 实例}
- Bean B 从 SingletonFactories 中获取 Bean C 实例,完成初始化;Bean A 从 EarlySingletonObjects 获取 Bean B 实例,完成初始化。
- EarlySingletonObjects 中的 A、B、C 实例清除,添加到一级缓存 SingletonObjects 中。
此时缓存状态:
SingletonObjects = {A 实例, B 实例, C 实例}
最终,Spring 通过三级缓存的协作,完成了 A、B、C 三个相互依赖的 Bean 的初始化,解决循环依赖问题。
具体使用了:
- 三级缓存 SingletonFactories 存储待初始化 Bean 的实例工厂;
- 二级缓存 EarlySingletonObjects 存储已实例化但未完成依赖注入的 Bean;
- 一级缓存 SingletonObjects 存储完全初始化结束的 Bean。
这三个缓存配合使用,使 Spring 容器有能力解决任意复杂度的循环依赖场景。
浙公网安备 33010602011771号