我有类层次结构,我想根据子类的类型使用CDI注入字段。 以下Java代码描述了这种情况:
@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
}
}
这些bean作为EAR的一部分打包了适当的ejb.jar存档,并且在适当的位置有beans.xml文件。代码在使用Java EE 7的Wildfly 10服务器上执行。
使用这段代码我得到层次结构基类的类(在这个特定情况下是类A),这是我认为它是逻辑的,因为注入点 场确实在A级。 关键是我想基于子类进行区分,尽管我注入了超类。
我可以使用InjectionPoint类来实现吗?有没有办法实现这个目标?
更多关于我想用这段代码实现的目标。此层次结构实现模板方法设计模式,所有类都是具体的,您可以使用实现通用算法和特定步骤的类A,但您可以选择重新定义某些子类中的步骤。此外,还需要注入特定的类型D,根据子类可能会有所不同。
不幸的是,人们强烈希望不重新设计低音A类。所以我试图找到一种方法,使用CDI在基类中注入一些东西,而不是使用部署描述符。
答案 0 :(得分:2)
根据您的问题,我了解您要确定将 bean 注入其中的内容。这可以通过以下方式实现:
@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
。
答案 1 :(得分: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的一部分)的要求。