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 是通过三级缓存机制来完成对象的初始化的。
具体的初始化过程如下:

  1. 创建 Bean A 时,发现其构造器需要 Bean B 的实例,但是 Bean B 还未初始化,所以:
  • 将 Bean B 的实例工厂添加到三级缓存 SingletonFactories 中;
  • Bean A 实例添加到二级缓存 EarlySingletonObjects 中;
    此时缓存状态:
SingletonFactories = {B 工厂}
EarlySingletonObjects = {A 实例}
  1. 创建 Bean B 时,发现其构造器需要 Bean C 的实例,但是 Bean C 还未初始化,所以:
  • 将 Bean C 的实例工厂也添加到三级缓存 SingletonFactories 中;
  • Bean B 实例也添加到二级缓存 EarlySingletonObjects 中;
    此时缓存状态:
SingletonFactories = {B 工厂, C 工厂}
EarlySingletonObjects = {A 实例, B 实例}
  1. 创建 Bean C 时,发现其构造器需要 Bean A 的实例,此时 Bean A 已在二级缓存中,所以:
  • 从 EarlySingletonObjects 中获取 Bean A 实例;
  • 将 Bean C 实例添加到 EarlySingletonObjects 中;
    此时缓存状态:
SingletonFactories = {B 工厂, C 工厂} 
EarlySingletonObjects = {A 实例, B 实例, C 实例}
  1. Bean B 从 SingletonFactories 中获取 Bean C 实例,完成初始化;Bean A 从 EarlySingletonObjects 获取 Bean B 实例,完成初始化。
  2. EarlySingletonObjects 中的 A、B、C 实例清除,添加到一级缓存 SingletonObjects 中。
    此时缓存状态:
SingletonObjects = {A 实例, B 实例, C 实例}

最终,Spring 通过三级缓存的协作,完成了 A、B、C 三个相互依赖的 Bean 的初始化,解决循环依赖问题。
具体使用了:

  1. 三级缓存 SingletonFactories 存储待初始化 Bean 的实例工厂;
  2. 二级缓存 EarlySingletonObjects 存储已实例化但未完成依赖注入的 Bean;
  3. 一级缓存 SingletonObjects 存储完全初始化结束的 Bean。
    这三个缓存配合使用,使 Spring 容器有能力解决任意复杂度的循环依赖场景。
posted @ 2023-04-29 00:02  咸蛋solo粥  阅读(58)  评论(0)    收藏  举报