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

Java 为什么Event.fireAsync()需要@ObservesAsync注释?,java,events,jakarta-ee,cdi,cdi-2.0,Java,Events,Jakarta Ee,Cdi,Cdi 2.0,在CDI 2.0中,通过调用Event.fireAsync(),然后使用@ObservesAsync带注释的侦听器侦听此事件 为什么我们同时需要事件.firesAsync()和@ObservesAsync CDI 2.0无法异步处理由event.fire()触发并被@ObservesAsync捕获的事件吗 或者反过来说,为什么CDI 2.0不能异步处理由event.fireAsync()和带有@的cauguth触发的事件 的确是一个很好的问题,这里有一些见解 CDI EG(专家组)决定不将这两

在CDI 2.0中,通过调用
Event.fireAsync()
,然后使用
@ObservesAsync
带注释的侦听器侦听此事件

为什么我们同时需要
事件.firesAsync()
@ObservesAsync

  • CDI 2.0无法异步处理由
    event.fire()
    触发并被
    @ObservesAsync
    捕获的事件吗
  • 或者反过来说,为什么CDI 2.0不能异步处理由
    event.fireAsync()
    和带有
    @的cauguth触发的事件

    • 的确是一个很好的问题,这里有一些见解

      CDI EG(专家组)决定不将这两者混合使用,原因如下:

      • 向后兼容性
        • 现有的应用程序使用同步,并且它需要表现出相同的行为
        • 保持相同的注释需要添加额外的选项来区分
      • 返回类型
        • 调用
          Event.fireAsync()
          将为您提供一个
          CompletionStage
          ,您可以使用
          excellective()
          thenApply()
          等链接后续步骤。这自然适合异步编程模型
        • 好的旧
          Event.fire()
          只会给你
          void
          ,你根本无法对它做出反应-这对异步不好
        • 同样,由于向后兼容,无法更改synchronous one的返回值
      • 除处理不同外,差异很大
        • 同步通知中的异常==链的末尾,您将爆炸
        • 异步通知中的异常==继续从观察者方法(可能来自多个线程!)收集所有异常,然后将它们展示给调用代码。因为它是
          完成阶段
          ,所以您可以很容易地对此做出反应
        • 混合使用这两种方法会在用户端导致一个非常混乱的结果——什么时候会爆炸,什么时候会继续?
          Event.fire()
          的真实结果是什么(如果它也是异步的话)
      • 内部观察者处理
        • 混合使用sync和async是非常复杂的(假设这是可能的)
        • 请记住,由于上下文不会在其他线程中传播(例如,
          RequestScoped
          需要通过焊接在异步观察者线程中重新激活),因此需要严格划分同步和异步之间的界限
        • 集成商的安全上下文传播也会带来类似的问题
        • 通常会对观察者进行预处理,以使其快速工作,如果两种方法都有一个观察者方法,则无法真正对其进行预处理,因为您永远不知道它将用于什么
      我能想到的当前模式的其他优点:

      • 存在
        fireAsync()
        允许您使用其他选项触发事件
        • 有一种所谓的方法,允许您为通知指定执行者
        • 这也为实施提供了更多火力——Weld已经通过这些选项提供了
      • 最后但并非最不重要的是用户体验
        • 通过这种方式,很明显,你以前的工作原理完全相同
        • 对于
          fireAsync()
          您有匹配的
          @ObservesAsync