【问题标题】:How does CDI injection work in MDBs and @Scheduled beans?CDI 注入如何在 MDB 和 @Scheduled bean 中工作?
【发布时间】:2011-06-05 08:32:36
【问题描述】:

我正在开发一个部署在 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。

【问题讨论】:

    标签: java-ee-6 cdi ejb-3.1 message-driven-bean jboss-weld


    【解决方案1】:

    使用 JBoss 专有注释 @Depends 或使用 jboss.xml 文件显式定义依赖关系可能会有所帮助。

    看到这个有点类似的问题:How to order deployment of EJBs and JMS queue config in JBoss 5?

    【讨论】:

    • 我已经考虑过这种可能性,但是与应用服务器无关是很重要的;出于远高于我的政治原因,我们可能会在不久的将来切换到另一个应用服务器。此外,我们真的必须依赖专有注解来使通用框架按预期工作吗?
    • 你说得对,我们不应该这样做。但是当事态发展时,有时需要一个切实可行的解决方案。使用 xml 文件时,您可能能够为所有其他主要服务器包含类似文件(顺便说一句,这些其他服务器是否也有这个问题?)。我同意这是一个丑陋的解决方案,希望其他人能够提供符合标准的答案。
    • 我猜你是对的。这不是我希望的答案,但我们当然必须务实。在这两个弊端中,我认为 XML 文件是较小的一个 - 至少这样我不会在源代码中引入 JBoss 特定的注释。我们已经有一些 JBoss 的部署描述符,当然无论如何都必须用新的应用服务器替换。在不久的将来,我们可能会迁移到 WebSphere,但我们还没有开始测试它。看看 WebSphere 是否表现出类似的行为会很有趣。
    • 确实如此。您今天可以检查 Glassfish 是否也有这种行为。关于不远的未来,我希望这个未来真的很近。尽管有 Websphere 8 的测试版,但尚未披露发布日期。保守的猜测会在 2012 年底发布最终版本。
    猜你喜欢
    • 2015-02-12
    • 2013-02-26
    • 2016-12-26
    • 1970-01-01
    • 2019-08-04
    • 2014-06-02
    • 1970-01-01
    • 2015-04-15
    相关资源
    最近更新 更多