繁体   English   中英

将CDI注入到现有对象实例中-与CDI 1.0一起使用,但不适用于CDI 1.1

[英]CDI Injection into existing object instance - worked with CDI 1.0 but not with CDI 1.1

由于我必须使用的框架的限制,我需要注入现有的对象实例(无法通过CDI本身照常创建它们)。 我的注入点用@EJB@Inject标记。

在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;
    }

}

如果我尝试在JBoss EAP 7.0,Java EE 7和CDI 1.1中执行相同的操作,则仅将标有@Inject的注入点注入到目标对象中,而标有@EJB的注入点不会注入(它们的值保持为null)。

我不明白为什么会这样。

是否可以通过JBoss EAP 7.0,Java EE 7和CDI 1.1注入现有对象,并填充@EJB注入点?


更新,2016-06-19,20:11

我刚刚发现,只要要注入的对象具有无参数构造函数,上述模式就可以工作。

示例-这可以工作

public class ExampleBean {

    private Dispatcher dispatcher;

    @Inject
    private SomeCdiBean someCdiBean;

    @EJB
    private SomeEjbService someEjbService;

    public ExampleBean() {
    }

    public ExampleBean(Dispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }

}

虽然这不起作用

public class ExampleBean {

    private Dispatcher dispatcher;

    @Inject
    private SomeCdiBean someCdiBean;

    @EJB
    private SomeEjbService someEjbService;

    public ExampleBean(Dispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }

}

在这种情况下,为什么CDI会检查默认构造函数的存在? (注意:bean 不是由CDI创建的,因此构造函数不应有任何区别)

可能的问题可能是, 没有 no-args构造函数的ExampleBean 被视为托管bean 集成商(Wildfly,EAP,glassfish等)只能向managed beans提供EE资源注入( @EJB是EE资源注入)。

引用Weld文档

集成商可能希望使用InjectionServices提供Weld提供的其他字段或方法注入。 与Java EE环境的集成可以使用InjectionServices为托管bean提供EE资源注入。

为了使ExampleBean成为managed bean并且不使用no-args构造函数,您需要声明一个@Inject注释的构造函数。

尽管我在这里只是一个疯狂的猜测,但不能真正确定为什么您说它可以与EAP 6和CDI 1.0一起使用。

仅作记录用途-据我所知,EAP 7包含CDI 1.2 (而不是1.1)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM