如果bean是Java EE 7(CDI 1.1)中的EJB bean,则injectPoint.getBean()返回null

A.P*_*zer 6 cdi ejb-3.1 glassfish-4 java-ee-7

我想从producer方法获取bean以读取其属性.在某些情况下,bean是一个EJB Singletonbean.

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

我的简单限定符:

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface InjectMe {}
Run Code Online (Sandbox Code Playgroud)

简单生产者:

@Dependent
public class SimpleProducer {

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

EJB(Singleton):

@Singleton
@Startup
public class SimpleSingleton {

    @Inject
    @InjectMe
    private String injectMe;

    @PostConstruct
    public void init() {
        System.out.println(injectMe);
   }
Run Code Online (Sandbox Code Playgroud)

}

控制台输出:

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

当我将Singletonbean 更改为CDIbean时,一切正常(ip.getBean()返回非null).它Java EE 6甚至可以用于Singleton豆类,但它没有Java EE 7.我正在使用Glassfish 4应用程序服务器.

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

小智 3

使用

injectionPoint.getMember().getDeclaringClass()
Run Code Online (Sandbox Code Playgroud)

在 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()
Run Code Online (Sandbox Code Playgroud)

该方法在旧的 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()
Run Code Online (Sandbox Code Playgroud)

并用注释生产者 bean

@javax.enterprise.context.ApplicationScoped
Run Code Online (Sandbox Code Playgroud)

注解。

  • 在weblogic 12.2.1(CDI 1.1)上测试,我也有同样的问题。虽然它在 weblogic 12.1.3 (CDI 1.0) 上运行良好。正如你所说,我使用“injectionPoint.getMember().getDeclaringClass()”解决了问题 (2认同)