我正在部署在JBoss 6 Final上的大型Java EE 6应用程序。我目前的任务涉及一致地使用@Inject而不是@EJB,但我遇到了一些类型的bean的问题,特别是@MessageDriven bean和具有@Scheduled方法的bean。CDI注入如何在MDB和@Scheduled bean中工作?
会发生什么情况是,如果我不喜欢时间(对于@Schedule)或者在启动时MDB队列中有消息,那么bean的实例化将失败,因为注入的资源(它们本身就是EJB)尚未约束。
因为我使用@Inject,我猜EJB容器认为我的bean准备就绪,因为容器本身不关心@Inject;它可能只是假设由于没有@EJB注入,这些bean已准备好使用。注入的CDI代理将会失败,因为注入的资源实际上还没有绑定。
微小例如:
@Stateless
@LocalBean
public class MySupportingBean {
public void doSomething() {
...
}
}
@Singleton
public class MyScheduledBean {
@Inject
private MySupportingBean supportingBean;
@Schedule(second = "*/1", hour = "*", minute = "*", persistent = false)
public void onTimeout() {
supportingBean.doSomething();
}
}
上面的例子可能不会经常因为只有两个豆失败了,但我工作的项目结合大量的EJB,这将放大的问题。但是它可能会失败,因为不能保证MySupportingBean首先被绑定,并且如果在MySupportingBean被绑定之前调用了onTimeout,那么MyScheduledBean的实例化将失败。如果我使用@EJB,MyScheduledBean将不会被绑定,直到对MySupportingBean的依赖得到满足。
请注意,该示例在onTimeout本身不会失败,但是当CDI尝试注入MySupportingBean时。
我读过很多帖子,在很多人认为@Inject总是比较好的论坛上。一般来说,我同意,但他们如何处理与@Inject结合的@Schedule或@MessageDriven?根据我的经验,在这些情况下,无论bean是否工作,这都归结为愚蠢的运气,并且bean将随意失败,具体取决于EJB的部署顺序以及何时调用@Schedule或onMessage。
我已经考虑过这种可能性,但作为应用服务器是无关的是样很重要;出于政治原因,我们很可能会在不久的将来转向其他应用服务器。此外,我们是否真的必须依靠专有注释来使通用框架按预期工作? – 2011-01-10 07:26:05