events - 事件触发时 CDI 观察器尚未初始化

标签 events cdi wildfly java-ee-7 ejb-jar.xml

我有两个 SLSB:

  • BeanF
  • BeanO

在两个 ejb-jar 中:

  • ModF,
  • ModO

BeanF 触发一个事件,而 BeanO 观察它。

第一个 fire(-) 操作以异常结束 (Wildfly 8.2):

ERROR [org.jboss.as.ejb3.invocation] JBAS014134: EJB Invocation failed on component BeanF for method public void BeanF.publish(ModEvent):
javax.ejb.EJBException: org.jboss.msc.service.ServiceNotFoundException: Service service
jboss.deployment.subunit."myapp.ear"."modO.jar".component.BeanO.VIEW."BeanO".LOCAL not found

进一步的fire(-)操作到达观察者,但我不能让任何事件丢失。

有没有办法在事件触发之前强制观察者初始化(或者在事件触发并等待处理之后即时初始化)?

@Observes(notifyObserver = Reception.IF_EXISTS) 仅允许在观察者尚未准备好时静默跳过事件。
在我的例子中,BeanF 不能依赖于 BeanO,因为 ModO 必须在 中的 ModF 之后声明。 application.xml.

可以使用 CDI 事件/监听器吗?还是需要使用 JMS?

最佳答案

其他实验

尝试使用 @Singleton@Startup 注释两个 bean,并收到相同的异常(我无法使用 @DependsOn 注释 BeanF ( BeanO ) 因为 ModF 看不到 ModO)。 还尝试将 BeanO 更改为 @ApplicationScoped 在这种情况下可以接收事件 - BeanO.observe(@Observes ...) 方法开始执行,执行了一些日志记录,但在尝试调用其他 @Stateless bean 时崩溃并出现 ServiceNotFoundException 异常(此其他 bean 必须是 @Stateless 因为它使用 TransactionAttributeType.REQUIRES_NEW 注释)。

CDI 解决方案

有点丑陋但可行的解决方案:缓存/排队事件:将 BeanO 拆分为两个 bean:BeanO1BeanO2。让 BeanO1 是一个 @ApplicationScoped bean,让它观察事件并通过调用一些空方法并捕获 来检测 BeanO2 是否准备好ServiceNotFoundException。如果 BeanO2 不存在,则事件将在 BeanO1ConcurrentLinkedQueue 中排队。 BeanO2 是无状态的,除了观察之外,它可以执行 BeanO 所做的所有事情。当事件到达并且 BeanO2 准备就绪时,BeanO1 首先从队列中推送事件。仅当存在实际触发处理旧事件的其他事件时,这是可接受的。

JMS

我认为使用 JMS 将是最干净的解决方案,但也存在一些陷阱:

  • 如果使用topic,那么我们可能会再次陷入原来的问题 - 订阅者在发送第一条消息后注册(不确定规范,但如果没有消息,消息就会丢失)订阅者)。
  • 如果使用 queue,则当在其他产品中使用 ModF 并且没有 ModO 时,可能会出现问题 - 队列将膨胀,这可能不是 super 肠道。
    • 也许 ModF 可以定义一些读取所有事件的 MDB 并丢弃它们,并且 ModO 以某种方式注册自己的 MDB具有更高优先级的(只是猜测,不知道这是否可能)
    • 也许ModO可以包含一个带有队列名称的配置文本文件,以便ModF可以读取该文件,动态初始化与队列的连接并将事件放入该队列(如果没有 ModO 并且没有文件,则 ModF 不会触发事件。

关于events - 事件触发时 CDI 观察器尚未初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29488876/

相关文章:

java - 将数据库 session 注入(inject)服务的调度程序的 CDI 范围

jboss - Wildfly:意外元素 '{urn:jboss:domain:4.2}server'

javascript - 触发两个事件时运行代码

c# - 我可以只举办没有委托(delegate)的事件吗?

jsf - JSF 中基于 CDI 接口(interface)的 bean

java - Jersey 2.17 中的依赖注入(inject)

ios - 使用 WildFly 迁移到 JDK 10 和 JSF 2.3 后,iOS 和 Mac OSX 上的站点渲染中断

json - 如何在resteasy和wildfly 8.2中转储http请求正文

c# - 在 C# 中捕获和发送键盘/鼠标输入

.net - 在进程关闭期间处理 ObjectDisposedException 和类似异常?