【发布时间】:2012-09-02 11:08:36
【问题描述】:
我刚刚在Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean 上阅读了关于各种托管 bean 及其关系的非常好的解释,当我在应用程序中遇到一个烦人的问题时,我想知道是否可以控制或影响 bean 的方式和时间开始。
在我的 Java EE 应用程序中,我使用 EJB、CDI 和 JSF2 作为视图技术。通过 SPI 启动来自第三方的服务,并配置一个作业执行器来启动作业并处理其他与计时器相关的内容。当作业执行器完成其引导时,会立即执行一项作业。该作业使用 CDI 注入来访问某些 bean,其中一个 bean 使用 EJB。
现在的问题是大多数时间 Java EE 6 服务器 (JBoss 7.1.1) 启动 EJB 仍然不可用,然后作业尝试访问它。抛出异常并且作业失败,并且构建服务以停用该失败的作业。好吧,停用失败的工作似乎还不错。让作业重新启动和运行的唯一解决方案是取消部署并再次重新部署。不幸的是,这是一项手动任务,无法以编程方式完成。
而且,让事情变得糟糕:在极少数情况下,这不会发生。
所以,我现在的问题是:我能否以某种方式控制 EJB 和 CDI bean 的初始化和部署,以便我可以确保在初始化 CDI bean 之前初始化所有 EJB bean?
我在 EARs application.xml 中将 initialize-in-order 设置为 true 并设置 EJB 的顺序,以便它们按照我需要的方式进行初始化(EJB 核心,然后是 EJB 业务,然后是 WAR),但是基于 CDI 的服务作为 JAR 放置在 lib 文件夹中。
【问题讨论】:
-
您是否尝试过使用 CDI 的
Events功能? -
例如在 EJB
@PostConstruct中触发一个事件,您的服务会观察到该事件。 -
@tair no.我不知道我可以为自己触发 CDI 事件 :) 你的意思是我可以从服务所依赖的所有 EJB 触发事件然后对其采取行动?例如阻止或释放作业?
-
是的。另一种解决方案是创建一个
@Startup MyServiceEjb,其中@DependsOn是运行服务所需的所有EJB。 -
如何自动启动 CDI bean?