如果bean是Java EE 7中的EJB bean(CDI 1.1)

时间:2016-01-06 22:09:52

标签: cdi ejb-3.1 glassfish-4 java-ee-7

我想从producer方法获取bean以读取其属性。在某些情况下,bean是EJB Singleton bean。

我简化了我的代码以专注于这个问题。

我的简单限定符:

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface InjectMe {}

简单的制片人:

@Dependent
public class SimpleProducer {

    @Produces
    @InjectMe
    public String getInjectMe(InjectionPoint ip) {
        // ip.getBean() returns null for some reason   
        return "ip=" + ip + ", bean=" + ip.getBean();
    }
}

EJB(Singleton):

@Singleton
@Startup
public class SimpleSingleton {

    @Inject
    @InjectMe
    private String injectMe;

    @PostConstruct
    public void init() {
        System.out.println(injectMe);
   }

}

控制台输出:

  

信息:ip = [BackedAnnotatedField] @Inject @InjectMe private com.test.ejb.SimpleSingleton.injectMe,bean=null

当我将Singleton bean更改为CDI bean时,一切正常(ip.getBean()返回非null)。它在Java EE 6中也可以使用Singleton bean,但它不在Java EE 7中。我正在使用Glassfish 4应用程序服务器。

是否在某处指定了此行为?

1 个答案:

答案 0 :(得分:2)

使用

injectionPoint.getMember().getDeclaringClass()

在WildFly 10.1.0中为我工作,我也在Payara Server 4.1.1.162 #badassfish(build 116)中快速测试了它。我还对全新的Payara Server 4.1.1.164 #badassfish(build 28)进行了测试。但是,我不得不将生产者bean的范围更改为@ApplicationScoped。默认范围不起作用。就我而言,它甚至有意义:)

injectionPoint.getBean().getBeanClass()

方法在旧的Payara中为我工作,但在新的WildFly 10.1.0.Final和新的Payara Server 4.1.1.164 #badassfish(build 28)中没有。

如果您查看Payara,当前的新版本164包含Weld 2.4.0.Final和WildFly 10.1.0Final使用版本2.3.5.Final。在这两个版本中,经典代码都不起作用!

结论是,在旧的CDI实现(Weld)上,它可以工作。在一些较新的Weld(在Payara 161中引入)中,行为发生了变化。我不知道这是否是故意的。

但是,解决方案是使用

injectionPoint.getMember().getDeclaringClass()

并使用

注释生产者bean
@javax.enterprise.context.ApplicationScoped

注释