2015-03-19 118 views
1

我有以下类别:CDI @Specializes和构造器注入与@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。如果我在项目中包含SpecialClass,则在“A”点打破NullPointerException

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

当开启豆专业另一个bean,其他bean是从来没有 由容器实例或调用。

不过,现在我要确保每一个@Specializes bean实现像

public SpecialClass() {} 

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

完整的构造函数,恕我直言,是一种反直觉的,并产生了大量的重复,样板代码,尤其是与像每个构造函数5-6个参数。另外,在创建新的专用bean时永远不会捕获它,因为项目总是仍然是编译清理的。

我做错了什么,或者有没有其他选择一遍又一遍地实施构造函数?

顺便说一句,我确实使用构造函数注入来创建容易测试的类,我只需使用构造函数来“注入”依赖关系的虚拟实现。

+0

当然,即使默认的原始java实例化也会失败。构造函数不会被继承,除了默认的无参数构造函数。 – maress 2015-03-19 15:42:27

+0

那么,我知道关于“原始”实例化,我曾希望CDI逻辑从我作为程序员带走了这个负担... ;-) – 2015-03-19 15:43:38

回答

1

CDI 1.1规格在4.3节说:

“的唯一办法一个bean可以完全在所有 注入点覆盖第二豆是,如果它实现了所有的bean类型,并声明 所有的预选赛第二个豆“。

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

+2

HInt:OmniFaces @ViewScoped在bean没有实现Serializable时抛出异常。 – BalusC 2015-03-20 08:31:34

+0

这是OmniFaces ViewScoped,因为我在JEE6/CDI 1.0上,但是1.0在该段落中声明了相同的规范。在该项目中使用专门的bean,所有工作正常,我只是在那个注入构造逻辑,我希望将以更简单的方式处理... – 2015-03-20 09:41:44

+0

@BalusC感谢您的提示。 – jpangamarca 2015-03-20 13:48:50