29.Axon框架-事件(七)

Axon框架-事件(七)

1.事件的不可变特性的问题

在快速变化的需求中,事件定义也可能随时间迭代。事件存储是只读且仅支持追加的数据源,因此无论事件何时添加(多个版本的事件),应用都必须能够读取所有事件(应用必须能够处理多个版本的事件)

2.什么是事件升级

事件升级最初是面向对象编程的概念,指子类在需要时自动向上转型为其父类,该概念同样适用于事件溯源。事件升级即将事件从原始结构转换为新结构。与OOP的自动向上转型不同,事件升级无法完全自动化(旧事件不了解新事件的结构),需手动编写升级器(Upcaster),明确旧结构到新结构的转换规则

3.什么是Upcaster

Upcaster是一类特殊组件:接收版本为x的输入事件,输出零个或多个版本为x+1的新事件。此外,Upcaster以链式方式执行------前一个Upcaster的输出作为下一个Upcaster的输入。这种设计支持事件的增量更新:为每个新事件版本编写独立Upcaster,确保升级器小巧、解耦且易于理解

Axon框架中事件升级器的基础接口Upcaster,接收IntermediateEventRepresentation流作为输入,返回IntermediateEventRepresentation流作为输出。升级过程不会直接返回最终结果,而是通过堆叠中间事件表示,将多个版本间的升级函数链式串联。当最终结果被拉取时,才会对序列化事件执行实际的升级操作

4.事件升级的核心优势

事件升级最大的价值在于支持非破坏性重构------事件的完整历史记录保持不变,不会因结构变更丢失数据,这与DDD中事件溯源需保留完整业务轨迹的核心要求完全契合

5.配套组件

RevisionResolver

为了让Upcaster识别接收的序列化对象版本,事件存储会记录事件的版本号和全限定类名。版本号由序列化器中配置的RevisionResolver生成

IntermediateEventRepresentation

Axon的Upcaster不直接操作EventMessage,而是通过IntermediateEventRepresentation工作

6.Upcaster常见实现类和功能

介绍

不同序列化格式的处理

事件存储中可能存在多种序列化格式的事件(因使用了不同的Serializer实现)。升级时需注意IntermediateEventRepresentation的格式(会影响Upcaster实现),可通过canConvertDataTo验证中间表示是否支持目标类型

SingleEventUpcaster

EventMultiUpcaster与EventTypeUpcaster

特殊实现

7.实战

目标

适配Jackson序列化器

java 复制代码
public class ComplaintEvent1_to_2Upcaster extends SingleEventUpcaster {

   private static final SimpleSerializedType TARGET_TYPE =
           new SimpleSerializedType(ComplaintEvent.class.getTypeName(), "1.0");

   @Override
   protected boolean canUpcast(IntermediateEventRepresentation intermediateRepresentation) {
      return intermediateRepresentation.getType().equals(TARGET_TYPE);
   }

   @Override
   protected IntermediateEventRepresentation doUpcast(
           IntermediateEventRepresentation intermediateRepresentation
   ) {
      return intermediateRepresentation.upcastPayload(
              new SimpleSerializedType(TARGET_TYPE.getName(), "2.0"),
              com.fasterxml.jackson.databind.JsonNode.class, // Jackson序列化后的事件数据类型
              event -> {
                  // 强制转换为ObjectNode,添加description字段
                  ((ObjectNode) event).put("description", "no complaint description");
                  return event;
              }
      );
   }
}

8.执行顺序

介绍

选择Upcaster类型并实现后,需将其配置到应用中。核心注意事项:Upcaster必须按顺序执行。事件可能经历多次格式迭代,每个迭代版本都有对应的升级需求------由于单个Upcaster仅支持一个版本到下一个版本的转换,保持升级器的执行顺序至关重要

EventUpcasterChain是维护Upcaster顺序的核心组件,事件存储通过它将所有升级函数附加到事件流。多数场景下无需直接操作EventUpcasterChain

原生API

SpringBoot

相关推荐
Geoking.18 小时前
后端Long型数据传到前端js后精度丢失的问题(前后端传输踩坑指南)
java·前端·javascript·后端
lizhongxuan18 小时前
深入 Codex 沙盒
后端
架构谨制@涛哥19 小时前
架构谨制:重新定义软件从业者的本质
后端·系统架构·软件构建
ん贤19 小时前
Go GC 非玄学,而是 CPU 和内存的权衡
开发语言·后端·golang·性能调优·gc
码事漫谈1 天前
当AI开始“思考”:我们是否真的准备好了?
前端·后端
铁东博客1 天前
Go实现周易大衍筮法三变取爻
开发语言·后端·golang
oak隔壁找我1 天前
SpringBoot中MyBatis的Mapper的原理
后端
oak隔壁找我1 天前
Spring Boot 自动配置(Auto-configuration)的核心原理
后端
oak隔壁找我1 天前
Java的JAR包
后端
GetcharZp1 天前
告别 TCP 握手延迟!让你的 Go 服务瞬间拥抱 HTTP/3 时代
后端