2015-03-19 62 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