Spring源码学习:setter循环依赖

文章详细阐述了Spring框架处理setter循环依赖的过程,通过一个A和B类的案例展示了Bean实例化时如何在三级缓存中查找和创建对象,并最终解决循环依赖的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.案例:
@Component
public class A {
    private B b;

    @Autowired
    public void setB(B b) {
        this.b = b;
    }

    public B getB() {
        return b;
    }

    public void f(){
        System.out.println(b);
    }
}
@Component
public class B {
    private A a;

    @Autowired
    public void setA(A a) {
        this.a = a;
    }
    public void f(){
        System.out.println(a);
    }
}
public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        A a = ctx.getBean(A.class);
        a.f();
        System.out.println(a.getClass());
        System.out.println(a.getB().getClass());
    }
}
2.源码:

1.1.在三级缓存中查找a(没找到)

1.2.未找到,开始创建a的Bean实例

1.2.2.将实例对象包装为WrappedInstance

1.2.3.将该实例添加到第三级缓存中

1.2.4.开始初始化a实例的所有属性

1.2.4.1.开始初始化a的属性b,b是setter循环依赖属性

1.2.4.2.在三级缓存中查找b

1.2.4.3.未找到,开始创建b的Bean实例

1.2.4.4.通过反射对B类实例化

1.2.4.5.将实例对象包装为WrappedInstance

1.2.4.6.将该实例添加到第三级缓存中

1.2.4.7.开始初始化b实例的所有属性

1.2.4.7.1.开始初始化b的属性a,a是setter循环依赖属性

1.2.4.7.2.在三级缓存中查找a

1.2.4.7.3.在第三级缓存中找到,获取a的实例

重复1.1.的工作

1.2.4.7.4.将a实例从第三级缓存降到第二级缓存

1.2.4.7.5.初始化b实例的所有属性结束,b的Bean创建完成

1.2.4.7.6.将b添加到第一级缓存,并从后两级中移除

1.2.4.8.初始化a实例的所有属性结束,a的Bean创建完成

1.2.4.9.将a添加到第一级缓存,并从后两级中移除

3.流程总结:

1.开始实例化a

1.1.在三级缓存中查找a

1.2.未找到,开始创建a的Bean实例

1.2.1.通过反射对A类实例化

1.2.2.将实例对象包装为WrappedInstance

1.2.3.将该实例添加到第三级缓存中

1.2.4.开始初始化a实例的所有属性

1.2.4.1.开始初始化a的属性b,b是setter循环依赖属性

1.2.4.2.在三级缓存中查找b

1.2.4.3.未找到,开始创建b的Bean实例

1.2.4.4.通过反射对B类实例化

1.2.4.5.将实例对象包装为WrappedInstance

1.2.4.6.将该实例添加到第三级缓存中

1.2.4.7.开始初始化b实例的所有属性

1.2.4.7.1.开始初始化b的属性a,a是setter循环依赖属性

1.2.4.7.2.在三级缓存中查找a

1.2.4.7.3.在第三级缓存中找到,获取a的实例

1.2.4.7.4.将a实例从第三级缓存降到第二级缓存

1.2.4.7.5.初始化b实例的所有属性结束,b的Bean创建完成

1.2.4.7.6.将b添加到第一级缓存,并从后两级中移除

1.2.4.8.初始化a实例的所有属性结束,a的Bean创建完成

1.2.4.9.将a添加到第一级缓存,并从后两级中移除

4.三级缓存机制

一级:初始化完成的Bean

二级:实例化待初始化的对象

三级:对象工厂类,提供对象代理功能

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼卡尼卡尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值