我该如何在Java中向可注入的构造函数传递参数?

3

我已经使用手动依赖注入有一段时间了,最近开始研究javax(JSR330)中的@Inject注解。

所以我有这样的代码:

public class MyClass {
    public MyClass(DepA depA, DepB depB) {
        this.depA = depA;
        this.depB = depB;
    }
}

我需要实例化它来使用,代码如下:

public void myMethod() {
    DepA depA = new DepA();
    DepB depB = new DepB();
    MyClass myClass = new MyClass(depA, depB);
}

然而,当我的依赖项有依赖项时,情况开始变得混乱,所以我阅读了一些资料并采用了这种方法(似乎每个人都认为可注入的构造函数是最佳实践):

public class MyClass {
    public MyClass() {}

    @Inject
    public MyClass(DepA depA, DepB depB) {
        this.depA = depA;
        this.depB = depB;
    }
}

使用方法如下:

public void myMethod() {
    MyClass myClass = new MyClass();
}

这似乎非常好用,但是有一个缺少的应用场景,我找不到答案:如果我想在我的构造函数中注入依赖项并使用实际参数怎么办?例如,是否可能像这样:
public class MyClass {
    public MyClass(String aContextualValue) {}

    @Inject
    public MyClass(DepA depA, DepB depB, String aContextualValue) {
        this.depA = depA;
        this.depB = depB;
        this.aContextualValue = this.aContextualValue;
    }
}

如果MyClass由DI管理,那么aContextualValue会从哪里来? - lexicore
@lexicore是我问题的主题。我猜我正在寻找类似于部分注入的东西?越想越觉得除了使用字段注入我的依赖项和构造函数来处理我的上下文参数之外,没有其他方法了。 - Cithel
请不要过度理论化。我只想知道 aContextualValue 是从哪里来的?你是从某个配置文件中读取它还是从用户那里获取的? - lexicore
@lexicore 噢,我误解了问题,我认为大多数情况下它会来自用户。 - Cithel
如果 aContextualValue 将来自用户,那么如何由 DI 容器进行管理? - lexicore
1个回答

3
如果(如您在评论中所说)aContextualValue来自用户,则无法真正注入它。因此,您无法完全让DI容器管理MyClass
相反,您可以实现类似于MyClassFactory的东西,它将为您生成MyClass
类似于:
public class MyClassFactory {

    private final DepA depA;
    private final DepB depB;

    public MyClassFactory(DepA depA, DepB depB) {
        this.depA = depA;
        this.depB = depB;
    }

    public MyClass createMyClass(String aContextualValue) {
        return new MyClass(this.depA, this.depB, aContextualValue);
    }
}

谢谢,太好了!我希望有一种方法可以避免写太多,但这确实做到了我所要求的 :) - Cithel
使用这种“传统”的(非CDI方法),你无法将MyClass实例注入到其他地方,或者我漏掉了什么?如果我想在用户提供构造参数值后注入MyClass实例,我应该怎么做? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接