我正在开发一个部署在 JBoss 6 Final 上的大型 Java EE 6 应用程序。我当前的任务涉及始终使用@Inject 而不是@EJB,但是我在某些类型的bean 上遇到了一些问题,特别是@MessageDriven beans 和带有@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();
}
}
上面的示例可能不会经常失败,因为只有两个 bean,但是我正在处理的项目绑定了很多 EJB,这会放大问题。但它可能会失败,因为不能保证首先绑定 MySupportingBean,如果在绑定 MySupportingBean 之前调用 onTimeout,则 MyScheduledBean 的实例化将失败。如果我改用 @EJB,则在满足对 MySupportingBean 的依赖之前,不会绑定 MyScheduledBean。
请注意,该示例不会在 onTimeout 本身失败,而是在 CDI 尝试注入 MySupportingBean 时失败。
我在不同的论坛上阅读了很多帖子,很多人认为@Inject 总是更好。一般来说,我同意,但他们如何处理@Schedule 或@MessageDriven 与@Inject 结合?以我的经验,在这些情况下 bean 是否可以工作归结为运气不好,并且 bean 将任意失败,具体取决于 EJB 的部署顺序以及何时调用 @Schedule 或 onMessage。