CDI注入现有对象实例 - 使用CDI 1.0但不使用CDI 1.1

时间:2016-06-19 09:49:36

标签: java-ee jboss cdi

由于我必须使用的框架的限制,我需要注入现有的对象实例(不能像往常一样通过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的注入点(它们的价值仍为空。)

我不明白为什么会这样。

有没有办法用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创建的,因此构造函数不应该有任何区别)

1 个答案:

答案 0 :(得分:0)

可能的问题可能是您的ExampleBean 没有 no-args构造函数不被视为managed bean。而积分器(Wildfly,EAP,glassfish,......)只能向@EJB提供EE资源注入(managed beans是EE资源注入)。

引自Weld doc

  

积分器可能希望使用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)。