为什么 Event.fireAsync() 需要 @ObservesAsync 注释?
Why Event.fireAsync() requires an @ObservesAsync annotation?
在 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()
和 cauguth 与 @Observes
触发的事件?
确实是个很好的问题,这里有点见识。
CDI EG(专家组)出于以下几个原因决定不混合这两者:
- 向后兼容
- 现有应用程序使用同步,它需要表现得一样
- 保持相同的注释将需要您添加额外的选项以进行区分
- Return类型
- 调用
Event.fireAsync()
会得到一个 CompletionStage
,您可以将后续步骤与 exceptionally()
或 thenApply()
等链接起来。这自然适合异步编程模型。
- 好旧
Event.fire()
只给你 void
,你根本无法反应 - 不适合异步
- 同样,由于向后兼容
,无法更改同步的 return 值
- 除了处理方式不同 很多
- 同步通知异常==链结束,你炸了
- 异步通知中的异常 == 您继续并从观察者方法(可能来自多个线程!)收集所有异常,然后将它们返回给调用代码。因为它是
CompletionStage
,你可以很容易地对此做出反应。
- 将两者混合会导致用户方面非常困惑 - 你什么时候会崩溃,什么时候继续前进?
Event.fire()
的真实结果是什么(如果它也是异步的)
- 内部观察者处理
- 混合同步和异步会非常复杂(假设甚至可能)
- 请记住,您需要在同步和异步之间严格划清界线,因为上下文不会在其他线程中传播(例如
RequestScoped
需要重新激活,由 Weld , 在异步观察者线程中)
- 集成商的安全上下文传播也有类似的问题
- 通常会对观察者进行预处理以使其工作得非常快,如果您对两者都有一个观察者方法,则无法真正对其进行预处理,因为您永远不知道它将用于什么
我能想到的当前模型的其他优点:
fireAsync()
的存在允许您使用其他选项触发事件
- 有所谓的
NotificationOptions
允许您为您的通知指定一个执行者
- 这也为实施提供了更多火力 - Weld 已经通过这些选项parallel execution and timeouts提供
- 最后但并非最不重要的 - 用户体验
- 这样就很清楚了,你之前的工作完全一样
- 而对于
fireAsync()
你有匹配的 @ObservesAsync
在 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()
和 cauguth 与@Observes
触发的事件?
确实是个很好的问题,这里有点见识。
CDI EG(专家组)出于以下几个原因决定不混合这两者:
- 向后兼容
- 现有应用程序使用同步,它需要表现得一样
- 保持相同的注释将需要您添加额外的选项以进行区分
- Return类型
- 调用
Event.fireAsync()
会得到一个CompletionStage
,您可以将后续步骤与exceptionally()
或thenApply()
等链接起来。这自然适合异步编程模型。 - 好旧
Event.fire()
只给你void
,你根本无法反应 - 不适合异步 - 同样,由于向后兼容 ,无法更改同步的 return 值
- 调用
- 除了处理方式不同 很多
- 同步通知异常==链结束,你炸了
- 异步通知中的异常 == 您继续并从观察者方法(可能来自多个线程!)收集所有异常,然后将它们返回给调用代码。因为它是
CompletionStage
,你可以很容易地对此做出反应。 - 将两者混合会导致用户方面非常困惑 - 你什么时候会崩溃,什么时候继续前进?
Event.fire()
的真实结果是什么(如果它也是异步的)
- 内部观察者处理
- 混合同步和异步会非常复杂(假设甚至可能)
- 请记住,您需要在同步和异步之间严格划清界线,因为上下文不会在其他线程中传播(例如
RequestScoped
需要重新激活,由 Weld , 在异步观察者线程中) - 集成商的安全上下文传播也有类似的问题
- 通常会对观察者进行预处理以使其工作得非常快,如果您对两者都有一个观察者方法,则无法真正对其进行预处理,因为您永远不知道它将用于什么
我能想到的当前模型的其他优点:
fireAsync()
的存在允许您使用其他选项触发事件- 有所谓的
NotificationOptions
允许您为您的通知指定一个执行者 - 这也为实施提供了更多火力 - Weld 已经通过这些选项parallel execution and timeouts提供
- 有所谓的
- 最后但并非最不重要的 - 用户体验
- 这样就很清楚了,你之前的工作完全一样
- 而对于
fireAsync()
你有匹配的@ObservesAsync