java - 为什么 Event.fireAsync() 需要 @ObservesAsync 注释?

标签 java events jakarta-ee cdi cdi-2.0

CDI 2.0 中的一个can fire an event asynchronously通过调用 Event.fireAsync(),然后使用带有 @ObservesAsync 注释的监听器来监听此事件。

为什么我们需要 Event.firesAsync()@ObservesAsync

  • CDI 2.0 不能异步处理由 Event.fire() 触发并被 @ObservesAsync 捕获的事件吗?
  • 或者相反,为什么 CDI 2.0 不能异步处理由 Event.fireAsync() 触发并被 @Observes 捕获的事件?

最佳答案

确实是一个非常好的问题,这里有一些见解。

CDI EG(专家组)出于以下几个原因决定不混合这两者:

  • 向后兼容性
    • 现有应用程序使用同步,它需要表现得一样
    • 保持相同的注释将需要您添加额外的选项以进行区分
  • 返回类型
    • 调用 Event.fireAsync() 会为您提供一个 CompletionStage,您可以将后续步骤链接到该 exceptionally()thenApply () 等。这自然适合异步编程模型。
    • 旧的 Event.fire() 只会给你 void,你根本无法对其使用react - 不利于异步
    • 同样,由于向后兼容,同步的返回值不能改变
  • 除了处理很多
    • 同步通知异常==链结束,你炸了
    • 异步通知中的异常 == 你继续收集来自观察者方法的所有异常(可能来自多个线程!),然后将它们返回给调用代码。由于它是 CompletionStage,您可以轻松地对此使用react。
    • 混合使用这两者会导致用户方面非常困惑 - 什么时候会崩溃,什么时候继续? Event.fire() 的真实结果是什么(如果它也是异步的)
  • 内部观察者处理
    • 混契约(Contract)步和异步会非常复杂(假设它甚至是可能的)
    • 请记住,您需要在同步和异步之间严格划清界线,因为上下文不会在其他线程中传播(例如 RequestScoped 需要重新激活,通过焊接,在异步观察者线程中)
    • 集成商的安全上下文传播也存在类似的问题
    • 通常会对观察者进行预处理以使其工作得非常快,如果您对两者都有一个观察者方法,则无法真正对其进行预处理,因为您永远不知道它将用于什么

我能想到的当前模型的其他优点:

  • fireAsync() 的存在允许您使用其他选项触发事件
  • 最后但并非最不重要的一点 - 用户体验
    • 这样很明显,你之前的工作完全一样
    • 对于 fireAsync() 你有匹配的 @ObservesAsync

关于java - 为什么 Event.fireAsync() 需要 @ObservesAsync 注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44586297/

相关文章:

java - 节点数组 toString Java

silverlight - 如何在 MVVM Light 中关闭 TabItem

javascript - 识别哪个 JS 脚本正在执行该事件

jakarta-ee - 未找到 JEE6 教程示例

jakarta-ee - 使用 Struts 2 标签时新变量到底位于哪里?

java - 无法在 onSaveInstanceState 中 bundle 数据

java - 发送大文件(~ 1GB)失败并出现 SocketException

java - 有关解释死锁的 oracle.com 并发代码的问题

vb.net - 音频文件类

jquery - 使用 JQuery GAE Dropload 时出现问题 - 通过拖放上传 Blobstore