可以从 sagas 和聚合中预定义 Deadline。 DeadlineManager 组件负责 调度 Deadline 并在 deadline 到达时调用 @DeadlineHandler 。 DeadlineManager 可以作为资源注入。 它有两种风格:SimpleDeadlineManager 和 QuartzDeadlineManager 调度 Deadline 可以通过提供 Duration 来预定义 Deadline,在此之后将触发它(或将触发它的 Instant )和 deadline 名称。 调度 Event 或 调度 Deadline 与事件调度不同,当预定义 deadline 时,将不会存储已发布的消息。 预定义/触发 deadline 不涉及 EventBus (或 EventStore ),因此不存储消息。class DeadlineSchedulingComponent { void scheduleMyDeadline() { String deadlineId = deadlineManager.schedule(Duration.ofMillis(500), "myDeadline"); // For example store the `deadlineId` } } 结果我们收到了一个 deadlineId ,它可以用来取消 deadline。 在大多数情况下,将 deadlineId 作为一个字段存储在您的 Aggregate/Saga 中是最方便的。 当某个事件意味着先前调度的 deadline 已过时(例如,支付 invoice 的 deadline,但客户支付了金额,这意味着 deadline 已过时并且可以取消)时,取消 deadline 可能会派上用场。class DeadlineCancelingComponent { void cancelMyDeadline(String deadlineId) { deadlineManager.cancelSchedule("myDeadline", deadlineId); } } 请注意,在前面提到的旁边还有更多选项可以取消 deadline:cancelAll(String deadlineName) 取消与给定 deadlineName 匹配的每个预定义的 deadline。 请注意,这也因此取消了与名称匹配的其他聚合和/或 saga 实例的 deadline。cancelAllWithinScope(String deadlineName) 取消给定 deadlineName 匹配的预定义 deadline,在 Scope 中调用该方法。 例如,如果从 "聚合实例 X" 中执行此操作, "聚合实例 X"中的 ScopeDescriptor 将用于取消。cancelAllWithinScope(String deadlineName, ScopeDescriptor scope) 取消给定 deadlineName 和 ScopeDescriptor 匹配的预定义 deadline。 这允许从不同的作用域按名称取消 deadline,然后是执行它的作用域。 如果您在处理 deadline 时需要有关 deadline 的上下文数据,您可以在安排 deadline 时附加 deadline 有效负载:class DeadlineSchedulingWithPayloadComponent { void scheduleMyDeadlineWithPayload() { String deadlineId = deadlineManager.schedule( Duration.ofMillis(500), "myDeadline", new MyDeadlinePayload(/* some user specific parameters */) ); // For example store the `deadlineId` } }处理 Deadline 我们现在已经了解了如何预定义 deadline。 当达到预定时间时,会调用相应的 @DeadlineHandler 。 @DeadlineHandler 是一个消息处理程序,就像 Axon 中的任何其他处理程序一样 - 可以注入存在 ParameterResolver 的参数。 Deadline 的作用域 在预定义 deadline 时,会考虑 预定义 deadline 的上下文。 这意味着计划的 deadline 只会在其原始上下文中触发。 因此,您希望在 deadline 前调用的任何带有 @DeadlineHandler 注解的函数都必须位于计划的同一 Aggregate/Saga 中。 Axon 将此上下文称为 Scope 。 如有必要,实现并提供您自己的 Scope 将允许您在自定义的 "scoped" 组件中预定 deadline。 当在 deadline handler 上添加 @EndSaga 时,Saga 可以结束其生命周期。 @DeadlineHandler 根据 deadline 和 deadline 有效负载进行匹配。@DeadlineHandler(deadlineName = "myDeadline") public void on(MyDeadlinePayload deadlinePayload) { // handle the deadline } 如果在 @DeadlineHandler 中未定义 deadline 的名称,则将仅根据 deadline 有效负载进行匹配。@DeadlineHandler public void on(MyDeadlinePayload deadlinePayload) { // handle the deadline } 如果我们安排了一个没有特定负载的 deadline,@DeadlineHandler 不必指定负载。@DeadlineHandler(deadlineName = "payloadlessDeadline") public void on() { // handle the deadline }在你的应用程序中使用时间 在应用程序需要访问时钟的情况下,他们可以通过访问 GenericEventMessage.clock 来利用 EventMessage 中使用的时钟。 此时钟在运行时设置为 Clock.systemUTC ,并在测试期间进行操作以模拟时间。public void handle(PublishTime cmd) { apply(new TimePublishedEvent(GenericEventMessage.clock.instant())); } 请注意,当前时间戳会自动添加到 EventMessage。 如果处理程序只需要依赖事件发布的时间戳,他们可以直接访问该时间戳,如处理事件中所述。