2017-03-01 46 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的一部分)的代码的要求可能无法实现。