【问题标题】:If I use field injection with Guice, why can I only use the no arg constructor?如果我在 Guice 中使用字段注入,为什么我只能使用 no arg 构造函数?
【发布时间】:2022-04-22 13:56:38
【问题描述】:

这是一个例子:

public class Dog implements Animal{
    private  String color;

    @Inject
    private  Owner owner;

    //This constructor always used to build the Dog object.
    public Dog(){}

    public Dog(String random){}
}

这是限制还是默认行为?有没有办法使用参数化构造函数来构建 Dog 对象?这似乎是一个限制,所以我必须遗漏一些东西。

【问题讨论】:

    标签: java constructor dependencies guice code-injection


    【解决方案1】:

    使用 @Inject 注释您的其他构造函数

    想想看。 Guice 是一个依赖注入 (DI) 框架。这意味着 Guice 负责创建对象。

    因此,Guice 需要知道一些事情。其中第一个是如何创建新实例。因此,Guice(和大多数其他 DI 框架)就如何创建新对象提出了一些约定。

    Guice 创建对象的约定如下:要么提供无参数构造函数,要么使用@Inject 对其进行注释。为什么是无参数构造函数?因为它的所有参数都是已知的:没有。创建一个没有任何参数的对象很容易。

    如果有任何参数,例如您的示例中的String,Guice 怎么知道哪个String 注入?好吧,你可能会说你在一个模块中提供它,这很公平。但是在您的示例中,您有多个构造函数。 Guice 怎么知道要使用哪个构造函数?好吧,让我们标准化并说最容易构建的是允许的,但不是其他的。因此,让我们使用无参数构造函数进行实例化。

    请注意,您可以将字段注入与构造函数注入相关联,但要这样做,您最多必须使用@Inject 注释一个构造函数。以下代码完全有效:

    public class Dog implements Animal{
        private  String color;
    
        @Inject
        private  Owner owner;
    
        //This constructor always used to build the Dog object.
        public Dog(){}
    
        @Inject public Dog(String random){} // Note the @Inject annotation.
    }
    

    请注意,Guice's @Inject's Javadoc 相当明确(强调我的):

    正在构造的类必须恰好有一个用@Inject 标记的构造函数或者必须有一个不带参数的构造函数. `Injector 然后继续执行字段和方法注入。

    另外,请注意Javadoc of @javax.inject.Inject

    可注入构造函数使用@Inject 进行注释,并接受零个或多个依赖项作为参数。 @Inject 每个类最多可以应用一个构造函数。

    [...]

    @Inject 对于公共的、无参数的构造函数是可选的当没有其他构造函数存在时。这使注入器能够调用默认构造函数。

    [...]

    所以回答你的问题,,如果不使用 @Inject 注释它,就无法请求 Guice 使用 String 参数注入您的构造函数。

    【讨论】:

    • 啊,我不知道我们可以在构造函数上使用另一个 @Inject 注释。这是有道理的。谢谢 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2020-03-06
    • 2013-11-13
    • 1970-01-01
    • 2014-02-19
    • 2013-08-16
    相关资源
    最近更新 更多