为什么需要EventSourcingHandler(在聚合对象中)?

2024-04-09

公平警告:我不知道我在做什么,所以即使问这个问题也可能会出错。

我想要更新一个简单对象(聚合)的状态,然后向 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 执行您所期望的操作,查找实例并返回它。

这是我的问题:

  1. 为什么聚合中需要 EventSourcingHandler?这就对了 似乎可以工作,但结果不会存储或发送到任何地方。
  2. 所以,这成为我的下一个问题:执行 EventSourcing 后 Handler,是 Widget 的结果实例(不是投影) 存储、查看或发送到任何地方?
  3. 如果确实需要EventSourcingHandler,有什么办法可以避免 我的业务逻辑有两个独立的副本(一个在 EventSourcingHandler 和一个 EventHandler)?我真的很讨厌这个主意 必须在两个地方更新相同的业务逻辑。

我很感谢该小组能够提供的任何澄清。感谢您的帮助!


我希望我能帮助你解答这个问题!

简短的回答是: 使用的必要性@EventSourcingHandler实际上取决于您想要如何对应用程序进行建模。

现在,这并没有说明太多,所以让我详细说明一下为什么我这么说。 在回答您的问题时,我假设您的愿望是创建一个遵循 DDD、CQRS 和事件溯源思想的应用程序。因此,Axon 试图在构建应用程序时为您简化概念。

让我从这里回顾一下您的编号问题:

  1. 你需要的原因@EventSourcingHandler聚合中带注释的函数,是 (1) 根据 (2) 事件更新聚合状态it已发布。转到第 1 点,为什么要更新聚合的状态?由于聚合是应用程序的命令模型,因此它的任务是根据收到的命令做出决策。为了能够做出决策,有时聚合需要状态,但有时则不需要。所以在Widget你分享的例子,我假设color字段稍后根本不用于驱动业务逻辑,因此您可以完全从聚合中忽略此状态,不会出现任何问题。对于我的回应的第二点,我试图指出聚合只会处理源自自身的事件。这是因为事件是聚合的来源,因为事件构成了给定模型上发生的所有增量。
  2. 您的以下问题非常适合继续我在第 1 点中开始的解释。答案很简单,您的Widget聚合不存储在任何地方,不as is。每次您从以下位置检索聚合时Repository(这在 Axon 中会自动为您完成),默认为EventSourcingRepository在 Axon 中,将从事件存储中检索该给定聚合的所有事件。比,一个empty创建聚合实例,框架将重播它为该确切聚合实例找到的所有事件。因此,每次输入新命令时,您都会有效地对聚合进行事件溯源。这可能听起来有点矫枉过正,因为给定聚合的事件数量可能会增长到相当大的集合。这可以通过做类似的事情来解决快照 https://docs.axoniq.io/reference-guide/axon-framework/tuning/event-snapshots的聚合。
  3. 如果这种形式将您的应用程序拆分为处理业务逻辑的专用部分(命令模型)和仅返回查询模型作为答案的部分(查询模型),那么您可以决定采用状态存储聚合 https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/state-stored-aggregates。因此请注意,使用 Axon 时根本不需要进行事件溯源;这只是框架的默认操作方式。因此,我理解你的担忧,因为你在重复你的逻辑。但是,您可以严格分离做出要在聚合中保存的所有决策的部分。 查询模型(在您的示例中ProjectedWidget)可以以任何格式存储在您想要的任何数据库/工具中,理想情况下没有任何业务逻辑。 如果您确实发现自己在应用程序的查询端添加业务逻辑,这可能建议您应该将此位升级为源自聚合的事件。

我希望这能让您深入了解为什么要选择事件溯源。本文描述了CQRS https://axoniq.io/resources/cqrs比我在这里能做的更详细一点,并且this https://axoniq.io/resources/event-sourcing事件溯源链接;希望它们可以作为比我刚才给你的更彻底的解释。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么需要EventSourcingHandler(在聚合对象中)? 的相关文章

随机推荐

  • wireshark 和 tcpdump -r:奇怪的 tcp 窗口大小

    我正在使用 tcpdump 捕获 http 流量 并且对 TCP 慢启动以及窗口大小如何增加感兴趣 sudo tcpdump i eth1 w wget tcpdump tcp and port 80 当我使用 Wireshark 查看转储
  • 如何使用 jquery 淡入文本装饰 css?

    我有以下代码 This is a span sentence span 当用户将鼠标悬停在sentence 我希望在单词下方淡入下划线 这似乎是一个简单的问题 但我一直不知道如何最好地做到这一点 需要明确的是 我不能只使用css hover
  • Firefox 错误地记住单选按钮

    在 Firefox 7 0 1 中 我有两个复选框和许多其他输入 当我通过 jQuery 添加另一个输入时 Firefox 无法正确记住选择了哪些无线电输入 例如 如果我选择第一个单选按钮 然后刷新页面 则选择第二个单选按钮而不是第一个单选
  • 如何使用 Facebook Graph API 执行 FQL 查询

    我正在寻找一种使用新的 Open Graph API 执行 FQL facebook 查询语言 查询的方法 但没有成功 有谁知道我该怎么做 通过这个优秀的例子在这里找到了答案 http code google com p facebook
  • 无头 Linux 上的命令行“Android update sdk”

    如何在无头 Linux 服务器上更新 安装 Android SDK 平台 我得到的只是以下错误 似乎实际上不支持 更新 sdk 操作 android sdk linux 86 tools android verbose update sdk
  • 为什么有 2 种 AppFabric?

    我看到我们现在拥有 Windows Server AppFabric 和 Azure AppFabric 这只是 Microsoft 营销部门的命名空间冲突还是这些技术共享通用接口 有人告诉我 可以在本地生产服务器上使用 Azure App
  • 如何在 iOS 程序退出时关闭 UIManager 文档

    我有一个围绕全局 UIManagedDocument 核心数据 的 iOS 程序 我想知道如何确保它在程序退出之前正确保存和关闭 首先 如果我想确保在退出之前保存该文档 我应该 可以打电话吗 void closeWithCompletion
  • 如何在 socket.io python 服务器中获取连接客户端的会话 ID?

    我有这样的事情 from flask import Flask jsonify request render template Response from flask socketio import SocketIO emit app Fl
  • 如何将图例放在情节之外

    我有一系列 20 个图 不是子图 要在一个图中绘制 我希望图例是在盒子之外的 同时 我不想更改轴 因为图形的尺寸会减小 我想将图例框保留在绘图区域之外 我希望图例位于绘图区域右侧的外部 有没有办法减小图例框内文本的字体大小 从而使图例框的尺
  • Sequelize 创建具有关联的对象

    我正在尝试保存续集模型及其关联 所有关联都是一对一的 从数据库中检索具有关联的模型效果很好 但插入它们是另一回事 而且文档只会让我更加困惑 这是我的插入方法 models radcheck create user include model
  • 将csv文件导入access的VBA程序

    我需要 VBA 中的程序将数据从 csv excel 文件导入到 access 而不需要一些记录 如页眉和页脚 例如 我在 csv 文件中有一个表 其中包含一些 不属于表日期的句子 A1 这是一些句子标题 A2标题A3 A7 数据数据数据数
  • Azure VM的公共静态IP [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有什么方法可以赋值Azure VM 的公共静态 IP 我是否必须通过 Azure 虚拟网络进行操作
  • 如何使用 Tailwindcss 创建真正的粘性页眉/页脚(即使滚动也粘在底部)?

    很多博客和帖子声称使用 Tailwindcss 创建 粘性页脚 但我找不到thought关于内容超过简短的 hello world 行的情况 例如在none在这些示例中 如果主区域足够高可以滚动 则页脚会 粘住 https www goma
  • 用于分配视口元参数的脚本,iPhone / iPad 难题

    我正在使用 JavaScript 片段根据浏览器窗口的宽度设置视口元标记的内容参数 该脚本几乎完成了它应该做的事情 它将任何大屏幕设备的初始比例值设置为 1 将纵向模式下的 iPad 设置为 0 5 并将任何屏幕宽度小于 700px 的设备
  • numpy 广播如何执行得更快?

    在下面的问题中 https stackoverflow com a 40056135 5714445 https stackoverflow com a 40056135 5714445 Numpy 的广播提供了一种解决方案 其速度几乎比使
  • 使用支持 bean 的单个属性绑定两个 JSF 输入字段

    假设我有两个h inputText成分 我想将两个文本字段绑定到支持 bean 中的单个属性 问题是提交给支持 bean 的值是来自第二个文本字段的值 我希望该值应该从用户输入文本的字段提交 My code
  • 向特定联系号码发送 Whatsapp 消息(Swift 项目)

    我正在尝试向存储在全局变量中的收件人号码发送 Whatsapp 消息 通过使用这个简单的代码 let whatsAppUrl NSURL string whatsapp globalPhone if UIApplication shared
  • comonad 的简洁总结。 (其中 monad 是“不纯计算的类型”)

    就简洁的总结而言 这种对 Monad 的描述似乎胜出 https stackoverflow com questions 2488646 why are side effects modeled as monads in haskell 将
  • 通过扩展名限制可选文件[重复]

    这个问题在这里已经有答案了 如何通过扩展名限制可以使用 input type file 元素选择的文件 我已经知道接受属性 但在 chrome 中 它确实通过定义的最后一个 MIME 类型 在本例中为 gif 来限制文件 而 FF4 甚至不
  • 为什么需要EventSourcingHandler(在聚合对象中)?

    公平警告 我不知道我在做什么 所以即使问这个问题也可能会出错 我想要更新一个简单对象 聚合 的状态 然后向 UI 提供已更改对象的投影 这是我的聚合对象 命令处理程序存在 但此处未显示 Aggregate public class Widg