2017-03-01 75 views
1

我有類層次結構,我想根據子類的類型使用CDI注入字段。 這種情況在下面的Java代碼描述:CDI:基於對象類的注入

@Stateless 
public class A { 
    @Inject 
    @MyInjection 
    D d; 
    ... 
    public void templateMethod(){...}; 
    protected void step1(){...}; 
    protected void step2(){...}; 
} 

@Stateless 
public class B extends A { 
... 
    protected void step1(){...}; 
    protected void step2(){...}; 
} 

@Stateless 
public class C extends A { 
... 
    protected void step1(){...}; 
    protected void step2(){...}; 
} 

public class F { 

    @Produces 
    @MyInjection 
    D myProducer(InjectionPoint ip){ 
     Class<?> clazz = ip.getMember().getDeclaringClass(); 

     //if clazz is B then inject one type 

     //if clazz is C then inject other type 

     //default inject default type 
    } 
} 

這些咖啡豆包裝適當ejb.jar歸檔爲EAR的一部分,並且在適當的位置在beans.xml文件。該代碼是使用Java EE 7

使用此代碼我得到的類層次結構的基類(在這種特殊情況下A類),這是當我想它的邏輯,東陽InjectionPoint 場Wildfly 10服務器上執行確實在A級。 關鍵是我想根據子類別進行區分,儘管我在超類中進行了注入。

我可以使用InjectionPoint類實現這個嗎?有沒有什麼可能的方法來實現這一目標?

更多關於我想用這段代碼實現的內容。這個層次結構實現了模板方法設計模式,並且所有類都是具體的,可以使用實現一般算法和特定步驟的類A,但是您可以選擇重新定義某些子類中的步驟。還需要注入特定類型D,根據子類型可能會有所不同。

不幸的是,有強烈的願望不重新設計低音類A.所以我試圖找到我的方式注入基類使用CDI,而不是使用部署描述符的東西。

+0

請在你的問題中提到你試過的所有東西 –

回答

1

從你的問題我明白,你想確定什麼你注入它。這可以通過以下方式來實現:

@Produces 
@MyInjection 
D myProducer(InjectionPoint ip){ 
    // this will give you the class of the bean you injected into 
    ip.getBean().getBeanClass(); 
} 

爲了完整起見,你以前的解決方案中使用ip.getMember()返回一個Method對象(或Field現場製作)。因此,後續致電getDeclaringClass()會給你class A

+0

Siliarus感謝你的回答,但在我的特殊情況下,不幸的是ip.getBean()返回null。暫時對我來說這是一個難題。 –

+0

返回null?那麼,這可能意味着你在bean上有「錯誤的」範圍。因爲'InjectionPoint'只在注入'@ Dependent' bean的時候纔有效(閱讀更多[here](http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#injection_point))。 「A」,「B」和「C」豆的範圍是什麼? – Siliarus

+0

我相信這是'@ Dependent'。據我所知,如果bean沒有註釋,@Dependent是默認範圍。我錯了嗎? –

0

經過一番修補之後,我發現了一種實現我的問題中所述行爲的方法。這需要不同的CDI注入方法:代替現場注入構造注入完成了這項工作。

public class A { 
    D d; 
    ... 

    public A(){ 
     this.d = null; 
    } 

    @Inject 
    public A(@MyInjection D d){ 
     this.d = d; 
    } 
    ... 
    public void templateMethod(){...}; 
    protected void step1(){...}; 
    protected void step2(){...}; 
} 

@Stateless 
public class B extends A { 
    ... 
    public B(){ 
     super(); 
    } 

    @Inject 
    public B(@MyInjection D d){ 
     super(d); 
    } 
    ... 
    protected void step1(){...}; 
    protected void step2(){...}; 
} 

@Stateless 
public class C extends A { 
    ... 
    public B(){ 
     super(); 
    } 

    @Inject 
    public B(@MyInjection D d){ 
     super(d); 
    } 
    ... 
    protected void step1(){...}; 
    protected void step2(){...}; 
} 

public class F { 

    @Produces 
    @MyInjection 
    D myProducer(InjectionPoint ip){ 
     Class<?> clazz = ip.getMember().getDeclaringClass(); 

     //if clazz is B then inject one type 

     //if clazz is C then inject other type 

     //default inject default type 
    } 
} 

組織代碼這樣我能夠辨別基於葉類注射劑,雖然不改變基類(API的一部分)的代碼的要求可能無法實現。