[英]CDI Injection into existing object instance - worked with CDI 1.0 but not with CDI 1.1
Due to limitations of a framework I have to use, I need to inject into existing object instances (can't created them as usual via CDI itself). 由于我必须使用的框架的限制,我需要注入现有的对象实例(无法通过CDI本身照常创建它们)。 My injection points are marked either with
@EJB
or @Inject
. 我的注入点用
@EJB
或@Inject
标记。
With JBoss EAP 6.4, Java EE 6 and CDI 1.0 this worked perfectly fine with the following code: 在JBoss EAP 6.4,Java EE 6和CDI 1.0中,使用以下代码可以很好地工作:
public class DispatcherUtils {
public static <T> void inject(T anObject) {
BeanManager beanManager = getBeanManager();
Class<T> objClass = (Class<T>) anObject.getClass();
AnnotatedType<T> annotatedType = beanManager.createAnnotatedType(objClass);
InjectionTarget<T> injectionTarget = beanManager.createInjectionTarget(annotatedType);
CreationalContext<T> context = new IgnorantCreationalContext<>();
injectionTarget.inject(anObject, context);
injectionTarget.postConstruct(anObject);
}
private static BeanManager getBeanManager() {
try {
return (BeanManager) InitialContext.doLookup("java:comp/BeanManager");
} catch (final NamingException e) {
e.printStackTrace();
}
return null;
}
}
If I try to do the same in JBoss EAP 7.0, Java EE 7 and CDI 1.1 only injection points marked with @Inject
are injected into the target objects, those marked with @EJB
are not injected (their value remains null). 如果我尝试在JBoss EAP 7.0,Java EE 7和CDI 1.1中执行相同的操作,则仅将标有
@Inject
的注入点注入到目标对象中,而标有@EJB
的注入点不会注入(它们的值保持为null)。
I do not understand why that is. 我不明白为什么会这样。
Is there any way to inject into existing objects with JBoss EAP 7.0, Java EE 7 and CDI 1.1 and have @EJB
injection points populated as well? 是否可以通过JBoss EAP 7.0,Java EE 7和CDI 1.1注入现有对象,并填充
@EJB
注入点?
Update, 2016-06-19, 20:11 更新,2016-06-19,20:11
I just discovered that the above pattern works as long as the object I want to inject into has a no-arg constructor. 我刚刚发现,只要要注入的对象具有无参数构造函数,上述模式就可以工作。
Example - this works : 示例-这可以工作 :
public class ExampleBean {
private Dispatcher dispatcher;
@Inject
private SomeCdiBean someCdiBean;
@EJB
private SomeEjbService someEjbService;
public ExampleBean() {
}
public ExampleBean(Dispatcher dispatcher) {
this.dispatcher = dispatcher;
}
}
while this does not work : 虽然这不起作用 :
public class ExampleBean {
private Dispatcher dispatcher;
@Inject
private SomeCdiBean someCdiBean;
@EJB
private SomeEjbService someEjbService;
public ExampleBean(Dispatcher dispatcher) {
this.dispatcher = dispatcher;
}
}
Why does CDI check for the presence of a default constructor in such a case? 在这种情况下,为什么CDI会检查默认构造函数的存在? (Note: the bean is not created by CDI, so the constructor shouldn't make any difference)
(注意:bean 不是由CDI创建的,因此构造函数不应有任何区别)
Possible problem might be that your ExampleBean
without no-args constructor is not considered a managed bean . 可能的问题可能是, 没有 no-args构造函数的
ExampleBean
不被视为托管bean 。 And an integrator (Wildfly, EAP, glassfish,...) can only provide EE resource injection ( @EJB
being EE resource injection) into managed beans
. 集成商(Wildfly,EAP,glassfish等)只能向
managed beans
提供EE资源注入( @EJB
是EE资源注入)。
Quoting from Weld doc : 引用Weld文档 :
An integrator may wish to use InjectionServices to provide additional field or method injection over-and-above that provided by Weld.
集成商可能希望使用InjectionServices提供Weld提供的其他字段或方法注入。 An integration into a Java EE environment may use InjectionServices to provide EE resource injection for managed beans.
与Java EE环境的集成可以使用InjectionServices为托管bean提供EE资源注入。
To make ExampleBean
a managed bean
and not use no-args constructor, you need to declare a constructor annotated with @Inject
. 为了使
ExampleBean
成为managed bean
并且不使用no-args构造函数,您需要声明一个@Inject
注释的构造函数。
Though I am just taking a wild guess here and cannot really be sure why you say it worked with EAP 6 and CDI 1.0. 尽管我在这里只是一个疯狂的猜测,但不能真正确定为什么您说它可以与EAP 6和CDI 1.0一起使用。
And one more note just for the record - from my knowledge EAP 7 contains CDI 1.2 (rather than 1.1). 仅作记录用途-据我所知,EAP 7包含CDI 1.2 (而不是1.1)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.