我有以下课程:
@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,我确实使用构造函数注入来创建易于测试的类,我可以使用构造函数“注入”依赖项的虚拟实现。
答案 0 :(得分:1)
第4.3节的CDI 1.1规范说:
“一个bean可以完全覆盖第二个bean的唯一方法 注入点是它是否实现了所有bean类型并声明 第二个bean的所有限定符。“
您的基类使用命名限定符注释,而专门类不注释。您还应该使用Alternative标记它并在beans.xml中启用它。还有ViewScoped注释。除非它是Omnifaces的ViewScoped,否则看起来你将JSF托管bean与CDI bean混合在一起。