使用@ApplicationScoped @Named @Eager
,我的@EJB
注入的@Stateless
bean未正确实例化并评估为null
。
我有@ApplicationScoped @ManagedBean(eager=true)
用于安排一些工作。使用@Stateless
注释注入了一些@EJB
bean,并且工作正常。
在转向CDI注释时,我添加了OmniFaces @Eager
注释替代标准CDI中缺少的@ManagedBean(eager=true)
:
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.omnifaces.cdi.Eager;
@Named
@ApplicationScoped
@Eager
public class MyScheduler implements Serializable {
@EJB
private MyService myService;
@Inject
private MyNamedBean myNamedBean;
@PostConstruct
public void init() {
setupSchedulers();
}
@PreDestroy
public void destroy() {
destroySchedulers();
}
//...
}
使用此设置,在应用程序启动时正确调用@PostConstruct
方法(尽管它似乎在初始化上下文之前运行),但随后myService
计算为null
。< / p>
在日志中,会出现以下警告:
Severe: No valid EE environment for injection of org.omnifaces.cdi.eager.EagerBeansRepository
Severe: No valid EE environment for injection of my.package.MyScheduler
Info: Initializing Mojarra 2.2.8 ( 20140814-1418 https://svn.java.net/svn/mojarra~svn/tags/2.2.8@13507) for context '/tagific'
由于我需要从其他bean访问此bean,因此我无法使用@Singleton
和@Schedule
注释。
如何在@Stateless
应用程序作用域中正确地注入@Named
bean,这些bean将在应用程序启动时实例化?
答案 0 :(得分:4)
这看起来像是GlassFish中的初始化排序错误。 @Eager @ApplicationScoped
在ServletContextListener
中运行。显然,在这一点上,GlassFish还没有准备好注入EJB。这种结构适用于例如WildFly。
但是,在CDI中,在整个Java EE中统一各种不同的依赖注入方法的名称,您也可以使用@Inject
而不是@EJB
。 CDI代理能够进一步委派给正确的@Stateless
实例。
@Inject
private MyService myService;
您也可以在EJB内部使用@Inject
,但截至目前(Java EE 7),它还不支持自我引用。 @Asynchronous
方法。为此,你仍然要坚持@EJB
。
那就是说,您是否知道Oracle停止了对GlassFish的商业支持,您最好不要将其用于生产环境?另请参阅this blog。