【发布时间】:2016-04-11 04:08:06
【问题描述】:
我想从 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
@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() 返回不为空)。即使使用Singleton bean,它也可以在Java EE 6 中使用,但在Java EE 7 中不起作用。我正在使用 Glassfish 4 应用服务器。
这种行为是否在某处指定?
【问题讨论】:
-
听起来像玻璃鱼虫。
-
@JohnAment:不这么认为,WildFly 的行为也是如此。还不能回答这个问题,但可能的原因可能是:1)bean发现模块行为的改变(默认:
annotated); 2)注入(非上下文)类字符串; 3) 除了Dependent之外没有声明的范围 -
如果您调用
ip.getMember().getDeclaringClass(),您将获得两种情况下的 FQCN,这也用作 InjectionPoint API 文档中的示例,我在 Deltaspike 示例中看到它作为后续调用在bean之后是null。 -
@Alexander Rühl:谢谢您的回答。不幸的是,上述方法都不起作用:我已将发现模式更改为“全部”,更改了生产者 bean 的范围、生产者方法和单例 bean。将
@Singleton更改为@Stateless,将String类型更改为我自己的。我什至不能使用ip.getMember().getDeclaringClass(),因为在我的场景中,我将产生的值注入到一个抽象类中,并且需要从生产者方法访问基类(我需要它的注释),但ip.getMember().getDeclaringClass()返回抽象类。你已经写过你用 WildFly 试过了。它的工作方式相同吗? -
@A.Panzer:是的,尝试了同样的事情,但总是为空,不知道为什么。奇怪的是,它在 CDI 1.0 中的行为有所不同。可能您唯一能做的就是将 CDI 实现的源 jar 链接到您的项目,然后转到调用
getBean()gets 的位置。
标签: cdi ejb-3.1 glassfish-4 java-ee-7