使用@Postconstruct进行CDI @Specializes和构造函数注入

时间:2015-03-19 10:39:10

标签: jsf dependency-injection cdi postconstruct

我有以下课程:

@Named
@ViewScoped
public class BaseClass {
    private SomeDependency dep;

    public BaseClass(){}

    @Inject
    public BaseClass(SomeDependency dep) {
        this.dep = dep;
    }

    @PostConstruct
    private void initialize() {
        dep.doSomething(); // Point "A"
    }

    public String getProperty() {
        return "BaseClass-Property";
}

@Specializes
public class SpecialClass extends BaseClass() {

    @Override
    public String getProperty() {
        return "SpecialClass-Property";
    }
}

现在有些.xhtml我有类似

的东西
<h:outputText value="#{baseClass.property}" />

没有SpecialClass,这样可以正常工作。如果我在项目中包含NullPointerException,它会在点“A”处以SpecialClass打破。

嗯,根据to the Weld specification,这或多或少是预期的行为:

  

当启用的bean专门化另一个bean时,另一个bean永远不会   由容器实例化或调用。

然而,现在我必须确保每个@Specializes bean实现完整的构造函数,如

public SpecialClass() {}

@Inject
public SpecialClass(SomeDependency dep) { super(dep); }

其中恕我直言,有点反直觉,并产生大量重复的样板代码,特别是每个构造函数的5-6个参数。此外,在创建新的专用bean时永远不会捕获它,因为项目始终仍然是编译干净的。

我做错了什么或者没有其他方法可以反复实施构造函数?

BTW,我确实使用构造函数注入来创建易于测试的类,我可以使用构造函数“注入”依赖项的虚拟实现。

1 个答案:

答案 0 :(得分:1)

第4.3节的CDI 1.1规范说:

  

“一个bean可以完全覆盖第二个bean的唯一方法   注入点是它是否实现了所有bean类型并声明   第二个bean的所有限定符。“

您的基类使用命名限定符注释,而专门类不注释。您还应该使用Alternative标记它并在beans.xml中启用它。还有ViewScoped注释。除非它是Omnifaces的ViewScoped,否则看起来你将JSF托管bean与CDI bean混合在一起。