Guice 构造函数注入还是字段注入?

Guice Constructor injection or Field injection?

我是 Guice 新手。首选构造函数注入还是首选字段注入?

字段注入看起来既快速又简单,但由于缺少构造函数,测试将是一个挑战。

谢谢。

想指出一些差异,以便您自己决定:

  • 对于构造函数注入,您可以使用 final 修饰符。现场注入无法做到这一点。 final 成员的优势是题外话,您可以继续阅读。
  • 使用构造函数注入编写测试用例很容易(就像您已经提到的那样)
  • 对于构造函数注入,所有依赖项都是强制性的。为了声明一个 class 你需要知道它所有必需的依赖关系。
  • 通过字段注入,您将隐藏 class 的依赖项,而不是将它们显式化。

以上只是几点思考。我个人更喜欢构造函数注入,因为易于测试和 final 支持。

使用构造函数注入

Guice 团队在他们的 Minimize mutability wiki page 上说:

Minimize mutability

Wherever possible, use constructor injection to create immutable objects. Immutable objects are simple, shareable, and can be composed. Follow this pattern to define your injectable types:

[...]

Injecting methods and fields

Constructor injection has some limitations:

  • Injected constructors may not be optional.
  • It cannot be used unless objects are created by Guice. This is a dealbreaker for certain frameworks.
  • Subclasses must call super() with all dependencies. This makes constructor injection cumbersome, especially as the injected base class changes.

Method injection is most useful when you need to initialize an instance that is not constructed by Guice. Extensions like AssistedInject and Multibinder use method injection to initialize bound objects.

Field injection has the most compact syntax, so it shows up frequently on slides and in examples. It is neither encapsulated nor testable. Never inject final fields; the JVM doesn't guarantee that the injected value will be visible to all threads.

两种类型都可以。但是你需要知道何时何地需要使用构造函数注入。

构造函数注入的优点是,

  1. 它提供不变性(如果使用得当)
In Constructor Injection you can use something like this.

public class MemberResource {

     private final IMemberService memberService;

     @Inject
     public MemberResource(IMemberService memberService) {
         this.memberService = memberService;
     }

}

  1. 单元测试变得更容易。

Field injection 的优点是编码少。