构造函数注入与字段注入[重复]

Posted

技术标签:

【中文标题】构造函数注入与字段注入[重复]【英文标题】:Constructor injection vs Field injection [duplicate] 【发布时间】:2017-04-05 21:13:00 【问题描述】:

注入任何服务时,我有两种选择:

字段注入:

 @Inject 
 private MyService myService;

构造函数注入:

private MyService myService; 

@Inject
public ClassWhereIWantToInject(MyService mySerivce)
    this.myService = myService;

为什么构造函数注入优于字段注入

【问题讨论】:

这个错误的声纳描述是什么? 查看相关规则说明(this one)。然后,如果仍有不清楚的地方,我建议您通过对该实际描述的查询来更新您的问题。 非常感谢@Nicolas 【参考方案1】:

我发现场注入只有两个缺点。

在测试对象时很难注入模拟。 (可以通过 Mockito 的 @InjectMocks 解决)

循环依赖。如果 bean A 依赖于 bean B 并且 bean B 需要 bean A。如果你有构造函数注入很容易找到它。

【讨论】:

【参考方案2】:

做一些类似的事情(我假设你正在使用 spring-boot 或者你的 CDI 类似的东西)

public class ClassWhereIWantToInject

    private MyService myService; 

    @Inject
    public ClassWhereIWantToInject(MyService mySerivce)
        this.myService = myService;
    

在这个相关的question 中有一些有效的论据,为什么要通过构造函数使用注入而不是通过字段注入。归结为优点,您也可以在非 CDI 环境(即单元测试)中通过构造函数使用初始化,而无需添加更复杂的逻辑。

【讨论】:

我正在使用 EJB-CDI。问题是注入的最佳原因是:字段还是构造函数?答案是here 哈哈,太好了,我应该在打字之前先查看一下关于您问题的 cmets。我以为你想避免警告,这就是我添加这段代码的原因。【参考方案3】:

阅读这篇出色的帖子 (https://blog.marcnuri.com/field-injection-is-not-recommended/),我们可以更好地解释为什么 Field Injection 不是一个好的选择。

它不允许我们使用 final 关键字使字段不可变

这也离SRP单一职责原则)更远了,一旦拥有这个字段的类开始对第三方的初始化时间负有一些责任——派对课。

【讨论】:

【参考方案4】:

如果包含此注入的类将由框架(spring/ejb/cdi)注入,则字段注入将正确执行,否则(该类将由调用者使用 new 运算符实例化)它实际上是一个 NullPointerException 等待即将发生。在这种情况下,最好使用构造函数注入。

当注入将在框架注入的类中进行时,我们可以执行可靠的字段注入。

【讨论】:

以上是关于构造函数注入与字段注入[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Guice - 在构造函数中使用注入字段

当有多个实现接口的类时,如何指定构造函数注入[重复]

为啥在 CDI 中使用构造函数而不是 setter 注入?

IoC.Resolve 与构造函数注入

使用非默认构造函数和依赖注入为类创建Mockito测试

Spring基础篇(8)-Spring构造函数注入—实现子类的动态注入