警告:我不知道自己在做什么,所以即使问这个问题也可能会出错。
我想更新一个简单对象(聚合)上的状态,然后为UI提供更改后的对象的投影。这是我的聚合对象(命令处理程序存在,但未在此处显示)。
@Aggregate
public class Widget {
@AggregateIdentifier
private String id;
private String color;
...
@EventSourcingHandler
public void on(ChangeColorEvt evt) {
color = evt.getColor();
}
...
}
...这是我的预测:
public class WidgetProjection {
private final EntityManager entityManager;
private final QueryUpdateEmitter queryUpdateEmitter;
...
@EventHandler
public void on(ChangeColorEvt evt) {
ProjectedWidget projection = entityManager.find(ProjectedWidget.class, evt.getId());
projection.setColor(evt.getColor());
queryUpdateEmitter.emit(FetchWidget.class, query -> evt.getId().startsWith(query.getFilter().getIdStartsWith()), projection);
}
...
}
QueryHandler会执行您期望的事情,找到实例并返回它。
这是我的问题:
我感谢该小组可以提供的任何清晰度。感谢您的帮助!
答案 0 :(得分:2)
希望我能帮助您解决这个问题!
简短的答案是:
使用@EventSourcingHandler
的必要性实际上取决于您要如何为应用程序建模。
现在,这没什么多说的,所以让我详细说明为什么要说明这一点。 在回答您的问题时,我假设您的愿望是创建一个应用程序,在其中遵循DDD,CQRS和事件源的思想。因此,Axon在构建应用程序时会尝试为您简化的概念。
让我从这里浏览您编号的问题:
@EventSourcingHandler
带注释的函数的原因是(1)根据已发布的事件更新汇总状态。要转到第1点,为什么要更新聚合状态?由于聚合是应用程序的命令模型,因此它的任务是根据收到的命令进行决策。为了能够做出决定,聚合有时需要状态,但有时不需要。因此,在您共享的Widget
示例中,我假设以后根本不使用color
字段来驱动业务逻辑,因此您可以在Aggregate中完全省略此状态而无需任何操作问题。关于我的回答的第二点,我试图指出聚合将永远只处理源于自身的事件。这是因为事件是聚合的来源,因为事件构成了在给定模型上发生的所有增量。Widget
聚合不会存储在任何地方,而不是按原样存储。。每次您从Repository
(在Axon中自动为您完成)检索聚合(在Axon中默认为EventSourcingRepository
)时,该给定聚合的所有事件都会从活动商店。然后,将创建一个 empty Aggregate实例,并且该框架将重播针对该确切Aggregate实例找到的所有事件。这样,每次有新命令出现时,您就可以有效地对聚合进行事件搜索。这听起来有些过大,因为给定聚合的事件数量可能会增加到很大的数量。可以通过做诸如snapshots的聚合之类的事情来解决。ProjectedWidget
)可以以任何格式和所需的数据库/工具存储,理想情况下无需任何业务逻辑。
如果您确实发现自己在应用程序的“查询”端添加了业务逻辑,则可能建议您将此位升级为源自聚合事件的事件。我希望这能为您带来一些了解,为什么您首先要进行事件采购。本文比我在这里更详细地描述了State Stored Aggregate,并提供了CQRS的事件源链接;希望他们可以提供比我刚刚给您的更详尽的解释。