这是Guice的反模式吗?

时间:2012-04-07 18:39:01

标签: java dependency-injection guice

public class Widget {
    @Inject
    Fizz fizz;

    public Widget(Fizz fizz) {
        super();

        setFizz(fizz);
    }

    public void setFizz(Fizz fizz) {
        this.fizz = fizz;
    }
}

这是Guice的反模式吗?!?!

如果我说“fizz将被注入(通过@Inject)”,但是我允许构造函数和setter接受fizz,这是不必要的冗余吗?它会导致与Guice的注射器发生冲突吗?

我想我很困惑:

  • 何时应使用@Inject,vs。
  • 注释属性
  • 当您应该通过constructor / getter
  • 自己“注入”该属性时

有什么想法?提前谢谢!

3 个答案:

答案 0 :(得分:4)

为什么不使用这样的东西(即使用构造函数注入)?

public class Widget {
    private Fizz fizz;

    @Inject
    public Widget(Fizz fizz) {
        super();

        this.fizz = fizz;
    }

}

另见http://code.google.com/p/google-guice/wiki/Injections

答案 1 :(得分:3)

您应该使用构造函数注入来处理 REQUIRED 的依赖项。 当依赖关系为可选时,请使用属性注入

答案 2 :(得分:1)

我肯定会说这是一个问题,不是因为Guice不能这样做,而是因为你的代码有bug。 Guice将尝试调用默认的无参数构造函数(不存在)并失败。

但即使你添加了无参数构造函数,这仍然是一个反模式。我已经使用了DI框架一段时间,从未遇到过需要进行现场注入的问题。我确定它有一个用例,否则Guice的人不会包含它,但它会使你的代码无法在没有特殊代码的情况下进行测试,无论是字节码操作还是反射。

由于多种原因,构造函数注入通常是最好的。它使任何调用者清楚地知道你的依赖是什么,它允许你同时初始化所有类的不变量(避免部分初始化的类),它是唯一的DI风格,可以让你创建不可变对象,这是线程安全并降低程序复杂性。

我唯一用于方法注入的用例是当我不想要求子类声明父级的依赖项时,或者当我想要“可选”依赖项时,但这些很少见。