Spring的依赖注入及循环依赖解决

date
Apr 10, 2020
slug
Spring的依赖注入及循环依赖解决
status
Published
tags
Spring
summary
type
Post
最近看Spring的官方文档,看到依赖注入这一节,留意到一些比较需要注意的点,遂记录下;
Spring的常用注入方式就两种:
  • 构造器注入
  • Setter方法注入
这两种方法用优先哪种呢?看官方文档怎么说的:
notion image
翻译:
你可以混合使用两种注入方式,一个好的规则是对于强制性依赖使用构造器注入而可选依赖使用setter方法注入。另外使用对于使用Setter方法注入的属性可以加上@Require注解使得所注入的输入为必填。但是,对于使用构造方法注入这种编程方法验证参数的方法是最好的。
Spring团队推荐使用构造方法注入,因为它可以确保你的必需依赖不为null。此外,构造器注入会返回初始化状态给客户端(调用端)。但是要注意,构造方法有太多参数会造成坏味道的代码,实现这样的类会带来太重的负担,应该考虑如何重构代码更好的解决分离的问题。
Setter方法注入应该主要使用在可选依赖属性上并且应该设置默认值。另外,所有用到依赖属性的地方法都应该进行非空检查。Setter方法的一个好处是,类可以重新配置或者重新注入,这样使得类更合使用。使用JMX MBeans进行管理是Setter注入的一个经典例子。
使用哪种注入方式有时取决于某些特定类。有时,当处理一些没有源码的第三方类是,选择哪种方式取决于你。例如,如果一个第三方类没有暴露任何setter方法,那么构造器注入是唯一可以的方法。
 
那么循环依赖Spring文档又是怎么说的呢?
notion image
翻译:
如果你使用构造器注入,有可能会出现无法解决的循环依赖。
例如:A类通过构造器注入B类,B类通过构造器注入A类。如果你像A类B类那样配置互相注入,那么Spring IOC 容器运行时会检测到这个循环依赖,从而抛出BeanCurrentlyInCreationException.
一种可行的解决方式是修改代码将构造器注入改为Setter注入。或者,不使用构造器注入,只是用Setter方法注入。换一个说法,虽然不推荐,你可以使用Setter方法注入来配置循环依赖关系。
与经典的情况不同(没有循环依赖的情况),Bean A和Bean B之间的循环依赖关系会强迫其中一个bean在完全初始化之前注入到另外一个bean中(一个经典的先有鸡还是先有蛋情景)。
 

© Ryan Tang 2021 - 2025