构造函数注入vs场注入

Ria*_*adh 9 java dependency-injection cdi sonarqube

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

(现场注射)

 @Inject 
    private MyService myService;
Run Code Online (Sandbox Code Playgroud)

或(构造函数注入)

private MyService myService; 

@Inject
public ClassWhereIWantToInject(MyService mySerivce){
    this.myService = myService;
}
Run Code Online (Sandbox Code Playgroud)

为什么Constructor注射比Filed注射更好?

小智 8

阅读这篇优秀的文章(https://blog.marcnuri.com/field-injection-is-not-recommished/)我们可以找到关于为什么字段注入不是一个好的选择的更好的解释。

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

一旦拥有该字段的类开始对第三方类的初始化时序承担一定的责任,那么它就离SRP单一职责原则)又进一步了。


deh*_*asi 6

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

  • 当对象在测试中时很难注入模拟。(可以@InjectMocks从 Mockito解决)

  • 循环依赖。如果 beanA依赖于 beanB而 beanB需要 bean A。如果您有构造函数注入,则很容易找到它。


hec*_*o84 5

做类似的事情(我假设您正在使用spring-boot或与您的CDI类似的东西)

public class ClassWhereIWantToInject{

    private MyService myService; 

    @Inject
    public ClassWhereIWantToInject(MyService mySerivce){
        this.myService = myService;
    }
}
Run Code Online (Sandbox Code Playgroud)

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