Spring循环依赖难道只能通过两个Setter注入解决嘛?

本文探讨了Spring中循环依赖问题的解决方案,指出构造器注入与Setter注入结合能有效避免报错,关键在于控制依赖加载顺序。

Spring循环依赖难道只能通过两个Setter注入解决嘛?

先说结论:并不是,可以是一个setter和一个构造器

如果存在循环依赖的对象关系的话,位置靠上的类会先进行生命周期的加载

所以位置靠上的类必须通过set注入其他属性,这样才不会导致循环依赖的报错

前言

其实想到这个问题是由于网上给出的结论是

于是我便好奇了起来:为什么同样是一个通过Setter注入、一个通过构造器注入,会有两种不同的结果呢?

Setter注入与构造器注入

首先我们先明确哪种是setter注入,哪种是构造器注入

//setter注入
@Autowired
private B b;

//构造器注入
@Autowired
public B(A a) {
    this.a = a;
}

为什么可以一个通过set和一个通过构造器进行注入也不会导致循环依赖的报错

Spring默认在package从上至下加载Bean的生命周期:创建->注入->初始化完成
我们假设代码中,A所在位置在B上方

先构造器注入,再set注入

条件:A是构造器注入,B是set注入

由于A在上方那么会先进行A的生命周期

A在构造器创建实例时,由于容器中B是空的,导致A无法通过构造器创建对象,于是报错

即使为A添加了空参构造器也无济于事,因为使用构造器注入会先行调用有参构造器

先set注入,再构造器注入

条件:A是set注入,B是构造器注入

由于A在上方还是会先进行A的生命周期

此时,由于A有默认的无参构造器直接创建一个空对象放入了三级缓存,为其注入B时,发现容器中B是空的

于是开始B的生命周期,因为在三级缓存中A已经存在,所以B可以直接根据这个对象去通过构造器实例化

实际上是会因为引用了A,为A执行一个提前引用来创建一个动态代理对象放入二级缓存中,然后将二级缓存中A的代理对象给B,这里为了方便理解直接忽略了动态代理这一层缓存

于是B被创建、注入、初始化完成后加入到一级缓存,此时又来到了A的注入阶段,直接将B注入

于是A经过注入与初始化后,也加入到了IOC容器中,至此不会导致报错

所以可以得出结论:并不是只能通过两个Setter注入才能解决循环依赖的问题,也可以是一个setter和一个构造器

如果存在循环依赖的对象关系的话,位置靠上的类会先进行生命周期的加载

所以位置靠上的类必须通过set注入其他属性,这样才不会导致循环依赖的报错

结论依据:

  • 可以通过实现BeanPostProcessor前置调用类的方法将所有Bean依次输出
  • 也可以通过实现BeanNameAware的方法输出Bean的名称

总之我们会发现是B先被初始化完成后才初始化完成了A
所以是先创建了A,然后为其注入B时,启动了B的完整的一个生命周期,才会是B先被初始化完成的这样一个结果

【内容概要】:文档介绍了教育数据集-学生成绩数据,该数据集记录了学生在多个科目考试中的表现及相关的背景信息和社会经济特征。数据来源于葡萄牙两所中学的学生,涵盖了两个学期的成绩数据。数据集广泛应用于回归、分类、特征选择与降维等任务,旨在通过分析学生的个人、家庭、学校和社会环境等因素,预测学习成绩或识别影响成绩的关键因素。此外,还讨论了如何利用这些数据进行不平衡数据处理,并为制定有效的教育政策和个性化教育提供支持。【适用人群】:- 教育研究人员:研究影响学生成绩的因素,探索提升教育质量的方法。- 数据科学家与机器学习工程师:开发和评估各种机器学习模型,如回归、分类、聚类等。- 政策制定者:依据数据分析结果制定更有效的教育政策和干预措施。- 学术研究人员:用于教学和科研,特别是在教育数据分析领域。【使用场景及目标】:- 回归与分类模型评估:使用数据集评估不同机器学习算法的性能,预测学生成绩或分类学生群体。- 特征选择与降维:通过分析识别最重要的特征,优化模型性能并提高预测准确性。- 教育政策制定:帮助理解哪些因素对学生成绩有显著影响,指导教育资源的有效分配和支持策略。- 个性化教育:根据学生的表现和背景信息,推荐最适合的学习资源和教学方法,促进个性化学习和发展。此数据集为教育领域的研究和实践提供了丰富的资源,有助于推动教育质量的持续改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值