[英]CDI: Injection based on object class
I have class hierarchy where I would like to inject field using CDI based on type of subclass. 我有一个类层次结构,我想根据子类的类型使用CDI注入字段。 This situation is described in following Java code:
以下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
}
}
These beans are packaged appropriate ejb.jar archive as part of EAR and there is beans.xml file in proper place. 这些Bean作为EAR的一部分打包为适当的ejb.jar归档文件,并且在适当位置有beans.xml文件。 The code is executing on Wildfly 10 server using Java EE 7.
该代码正在使用Java EE 7在Wildfly 10服务器上执行。
Using this code I get class of hierarchy base class (in this specific case class A), which is when I think about it logical, beacause InjectionPoint field is indeed in class A. The point is that I would like to make distinction based on subclasses although I do inject in superclass. 使用此代码,我得到了层次结构基类的类(在这种情况下为A类),这是我认为合乎逻辑的原因,因为InjectionPoint字段确实在A类中。关键是我想根据子类进行区分尽管我确实注入了超类。
Could I achieve this using InjectionPoint class? 我可以使用InjectionPoint类实现此目的吗? Is there any possible way to achieve this?
有什么可能的方法来实现这一目标?
More on that what I would like to achieve with this piece of code. 这是我想通过这段代码实现的更多信息。 This hierarchy implements template method Design Pattern and all classes are concrete, you can use class A which implements general algorithm and specific steps, but you can opt out to redefine steps in some subclass.
该层次结构实现了模板方法“设计模式”,并且所有类都是具体的,您可以使用实现通用算法和特定步骤的类A,但是可以选择退出以重新定义某些子类中的步骤。 Also there is need to inject specific type D, which might be different based on sublclass.
另外,还需要注入特定的类型D,该类型根据子类可能有所不同。
Unfortunately there is strong desire not to redesign bass class A. So I am trying to find I way to inject something in base class using CDI and not using deployment descriptor. 不幸的是,强烈希望不要重新设计低音类A。因此,我试图找到一种方法,使用CDI而不是使用部署描述符在基类中注入某些东西。
From your question I understood that you want to determine what bean are you injecting it into. 根据您的问题,我了解到您想确定要将其注入到哪种bean中。 This can be achieved in the following way:
这可以通过以下方式实现:
@Produces
@MyInjection
D myProducer(InjectionPoint ip){
// this will give you the class of the bean you injected into
ip.getBean().getBeanClass();
}
For completeness, your previous solution used ip.getMember()
which returns a Method
objects (or Field
for field producers). 为了完整
ip.getMember()
,您先前的解决方案使用了ip.getMember()
,该ip.getMember()
返回一个Method
对象(或字段生产者的Field
)。 Therefore, subsequent call to getDeclaringClass()
will give you class A
. 因此,随后对
getDeclaringClass()
调用将为您提供class A
。
After a bit of tinkering I found a way to achieve behaviour stated in my question. 经过一番修补后,我找到了一种解决问题的方法。 This required different approach to CDI injection: instead of field injection constructor injection did the job.
这要求采用不同的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
}
}
Organizing code this way I am able to discriminate injection based on leaf classes, although the requirement of not changing code of the base class (part of an API) might not be possible to achieve. 尽管不更改基类(API的一部分)的代码的要求可能无法实现,但通过这种方式组织代码,我可以根据叶类区分注入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.