CDI 注入在 MDB 和 @Scheduled beans 中如何工作?
我正在开发一个部署在 JBoss 6 Final 上的大型 Java EE 6 应用程序。我当前的任务涉及一致使用 @Inject 而不是 @EJB,但我在某些类型的 bean 上遇到了一些问题,特别是 @MessageDriven bean 和带有 @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 的时间。
I'm working on a large Java EE 6 application that is deployed on JBoss 6 Final. My current tasks involve using @Inject consistently instead of @EJB, but I'm running into some problems on some types of beans, specifically @MessageDriven beans and beans with @Scheduled methods.
What happens is that if I'm unlucky with the timing (for @Schedule) or if there are messages in the MDBs' queues at startup, instantiation of the beans will fail because the injected resources (which are EJBs themselves) are not bound yet.
Because I use @Inject, I'm guessing that the EJB container considers my beans to be ready, since the container itself does not care about @Inject; it probably simply assumes that since there are no @EJB injections, the beans are ready for use. The injected CDI proxies will then fail because the resources to inject aren't actually bound yet.
Tiny example:
@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();
}
}
The above example will probably not fail often because there are only two beans, but the project I'm working on binds lots of EJBs, which will amplify the problem. But it might fail because there is no guarantee that MySupportingBean is bound first, and if onTimeout is invoked before MySupportingBean is bound, then instantiation of MyScheduledBean will fail. If I used @EJB instead, MyScheduledBean wouldn't be bound until the dependency to MySupportingBean was satisfied.
Note that the example will not fail in onTimeout itself, but when CDI attempts to inject MySupportingBean.
I've read a lot of posts on different forums where many people argue that @Inject is always better. Generally, I agree, but how do they handle @Schedule or @MessageDriven combined with @Inject? In my experience, it comes down to dumb luck whether the beans will work or not in those cases, and the beans will fail arbitrarily, depending on which order the EJBs are deployed in, and when @Schedule or onMessage are invoked.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用 JBoss 专有注释
@Depends
或使用 jboss.xml 文件显式定义依赖关系可能会有所帮助。请参阅这个有点类似的问题: 如何在 JBoss 5 中订购 EJB 和 JMS 队列配置的部署?
It might help to explicitly define the dependencies using the JBoss proprietary annotation
@Depends
or using the jboss.xml file.See this for a somewhat similar question: How to order deployment of EJBs and JMS queue config in JBoss 5?