在注入构造函数之前注入成员变量

时间:2017-06-27 08:40:52

标签: java dependency-injection

在类的注入构造函数中,我必须使用适当的参数调用超级构造函数。 super应该通过多态来调用子类的方法(我有来自实现相同方法的同一父类的多个子类)。 问题是子类中的方法依赖于已经注入成员变量。在我的例子中,子类依赖于不同类型的多个变量。 此外,父类是某些库中的本机类,我无法更改。 请参阅以下示例性,非常简化的代码:

public class A {

    @Inject
    public A(SomeType t)
    {
        workon(t1);
    }
}


public class B extends A{

    @Inject
    private MemberType mt;

    @Inject
    public B(SomeType t)
    {
        super(t)
    }

    public void workOn(SomeType t)
    {
        // mt is not set yet since this method
        // is called from the super constructor!
        mt.setT(t);
    }
}

除了手动初始化之外,有没有办法在调用继承方法之前注入成员变量?

2 个答案:

答案 0 :(得分:4)

您不应该从构造函数中调用可覆盖的方法。有很多文章解释了这一点,例如:http://www.javapractices.com/topic/TopicAction.do?Id=215

答案 1 :(得分:1)

MemberType的实例明确地注入A的构造函数中:

interface Workon {
    public void workon(SomeType t);
}

class MemberType implements Workon {
    public void workon(SomeType t) {
        this.setT(t);        
    }
}

class A {
    @Inject 
    public A(SomeType t, Workon w) {
        w.workon(t);
    }
}

class B extends A {
    private final MemberType mt;

    @Inject 
    public B(SomeType t, MemberType mt) {
        super(t, mt);
        this.mt = mt;
    }
}

通常,构造函数注入是你的朋友。如果一个类需要一个的东西,那么通常最好在构造函数中明确要求 thing ,因为那时你确定它已经准备就绪了。这有时需要提出新的事物。

在这种情况下,workon方法的特定行为会更改A的构造函数的行为;即它是A构造函数行为的参数,所以只需将其作为实际参数即可。

如果您无法更改A的构造函数,并假设A未明确依赖workon的结果,您还可以调用{的实际实现{1}}来自workon()的可能性:

B