我在一些关于 Spring MVC 和 Portlet 的文章中读到场注入不推荐。据我了解,场注入是当你注入一个 Bean 时@Autowired
像这样:
@Component
public class MyComponent {
@Autowired
private Cart cart;
}
在我的研究过程中,我还读到构造函数注入:
@Component
public class MyComponent {
private final Cart cart;
@Autowired
public MyComponent(Cart cart){
this.cart = cart;
}
}
这两种注射方式各有什么优点和缺点?
EDIT 1:由于这个问题被标记为重复这个问题 https://stackoverflow.com/questions/7779509/setter-di-vs-constructor-di-in-spring我查了一下。因为问题和答案中都没有任何代码示例,所以我不清楚我对我正在使用哪种注入类型的猜测是否正确。
注射类型
对于如何将依赖项注入到 bean 中,有以下三种选项:
- 通过构造函数
- 通过设置器或其他方法
- 通过反思,直接进入领域
您正在使用选项 3。这就是您使用时发生的情况@Autowired
直接在您的领域。
注射指南
Edit: 这里提到的这 3 个链接适用于 Spring 4.2。有关 2023 年 (6.09) 的较新版本文档,请参阅下面的列表
一般准则,Spring推荐的 http://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/beans.html(请参阅有关基于构造函数的 DI https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/beans.html#beans-constructor-injection or 基于 Setter 的 DI https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/beans.html#beans-setter-injection)如下:
- 对于强制依赖项或以不变性为目标时,请使用构造函数注入
- 对于可选或可更改的依赖项,请使用 setter 注入
- 大多数情况下避免现场注入
现场注入的缺点
现场注入不受欢迎的原因如下:
- 您无法像构造函数注入那样创建不可变对象
- 您的类与 DI 容器紧密耦合,无法在其外部使用
- 如果没有反射,您的类无法实例化(例如在单元测试中)。您需要 DI 容器来实例化它们,这使您的测试更像集成测试
- 您真正的依赖项对外部隐藏,并且不会反映在您的接口(构造函数或方法)中
- 拥有十个依赖项确实很容易。如果您使用构造函数注入,您将拥有一个带有十个参数的构造函数,这将表明某些内容存在可疑之处。但是您可以无限期地使用字段注入来添加注入字段。拥有太多依赖项是一个危险信号,表明该类通常会做不止一件事,并且可能违反单一职责原则。
结论
根据您的需要,您应该主要使用构造函数注入或构造函数和 setter 注入的某种组合。现场注入有许多缺点,应该避免。字段注入唯一的优点是编写起来比较方便,但这并不能抵消所有的缺点。
进一步阅读
我写了一篇关于为什么通常不推荐字段注入的博客文章:字段依赖注入被认为是有害的 http://vojtechruzicka.com/field-dependency-injection-considered-harmful/.
Spring文档
Spring 4.2(来自原始帖子)
- 国际奥委会容器 https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/beans.html
- 基于构造函数的依赖注入 https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/beans.html#beans-constructor-injection
- 基于 Setter 的依赖注入 https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/beans.html#beans-setter-injection
Spring 6.0.9(2023 当前稳定版本)
- 国际奥委会容器 https://docs.spring.io/spring-framework/reference/core/beans.html
- 基于构造函数的依赖注入 https://docs.spring.io/spring-framework/reference/6.1-SNAPSHOT/core/beans/dependencies/factory-collaborators.html#beans-constructor-injection
- 基于 Setter 的依赖注入 https://docs.spring.io/spring-framework/reference/6.1-SNAPSHOT/core/beans/dependencies/factory-collaborators.html#beans-setter-injection
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)