通过构造函数注入和使用 Guice 通过字段注释注入有什么区别?

Zha*_* Yi 3 dependency-injection guice

我有下面的代码使用 Guice 进行依赖注入。第一个是使用构造函数注入,而另一个是@Inject直接在字段上方添加。这两种方式有什么区别吗?Guice官网上好像推荐构造函数注入。

class BillingService {
    private final CreditCardProcessor processor;
    private final TransactionLog transactionLog;

    @Inject
    BillingService(CreditCardProcessor processor, TransactionLog transactionLog) {
        this.processor = processor;
        this.transactionLog = transactionLog;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

和:

class BillingService {
    @Inject
    private final CreditCardProcessor processor;
    @Inject
    private final TransactionLog transactionLog;
    BillingService() {

    }
    ...       
}
Run Code Online (Sandbox Code Playgroud)

Lac*_*lev 5

我要指出的差异:

  • 如果没有构造函数注入,您将无法使用final修饰符,即上面的代码将无法编译。在这里评论最终成员的优点是题外话。
  • 对于构造函数注入,所有依赖项都是强制性的。如果不了解每个声明的依赖项,您将无法实例化该类。
  • 使用构造函数注入编写测试用例可能会更容易(请参阅 The111 的答案)。
  • 还有另一种类型的 DI - setter 注入 - 它可以更自然地与构造函数注入混合(例如,用于分离强制依赖项和可选依赖项)。