Spring 如何解决 Bean 的循环依赖(循环引用)

@Component
public class A {
    
    @Autowired
    private B b;
    
}
@Component
public class B {
    
    @Autowired
    private A a;
    
}

上面的情况就是 循环依赖

Bean的创建初始化过程如下

如果不采取措施,那么循环依赖就会进入死循环

但 Spring 已经帮我们解决了大部分循环依赖问题

具体是如何解决的?

Spring解决循环依赖是通过三级缓存,对应的三级缓存如下所示:

缓存名称

源码名称

作用

一级缓存

singletonObjects

单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象

二级缓存

earlySingletonObjects

缓存早期的bean对象(生命周期还没走完)

三级缓存

singletonFactories

缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的

下图是Bean的生命周期,我们依照Bean的生命周期来说明,关于Bean的生命周期可以参考我的另外一篇博客

http://t.csdn.cn/DZz5zhttp://t.csdn.cn/DZz5z

一级缓存 存放 已经全部完成的Bean,可以直接使用

二级缓存 存放 早期的bean对象,其生命周期还没走完,也就是仅通过构造函数创建出实例,但未进行依赖注入及其以下初始化步骤

三级缓存 存放 对象工厂,对象工厂用于创建对象,其具体作用下面会说明

实际上 一级 和 二级 缓存就能解决一般的 循环依赖问题

但是 如果一个对象被增强了,即 是个代理对象, 这个时候就需要一个三级缓存

但是 仍有些循环引用 Spring 解决不了,这时候需要手动解决,最典型的就是 构造方法出现了循环依赖,如下

@Component
public class A {

    // B成员变量
    private B b;

    public A(B b){
        System.out.println("A的构造方法执行了...");
        this.b = b ;
    }
}
@Component
public class B {

    // A成员变量
    private A a;

    public B(A a){
        System.out.println("B的构造方法执行了...");
        this.a = a ;
    }
}

解决办法 -- 延迟加载:

public A(@Lazy B b){
    System.out.println("A的构造方法执行了...");
    this.b = b ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值