事件需要重定向到适当的 saga 实例。 为此,需要一些基础设施类。 最重要的组件是 SagaManager 和 SagaRepository 。Saga Manager 与处理事件的任何组件一样,处理是由事件处理器完成的。 但是,sagas 不是处理事件的单例实例。 他们有各自的生命周期,需要加以管理。 Axon 通过 AnnotatedSagaManager 支持生命周期管理,它被提供给事件处理器以执行处理程序的实际调用。 它使用要管理的 saga 的类型以及可以存储和检索该类型的 saga 的 SagaRepository 进行初始化。 单个 AnnotatedSagaManager 只能管理单个 saga 类型。 使用配置 API 时,Axon 将为大多数组件使用合理的默认值。 但是,强烈建议定义一个 SagaStore 实现来使用。 SagaStore 是在某处"物理"存储 saga 实例的机制。 AnnotatedSagaRepository (默认)使用 SagaStore 来存储和检索需要的 Saga 实例。 Axon Configuration API Configurer configurer = DefaultConfigurer.defaultConfiguration(); configurer.eventProcessing(eventProcessingConfigurer -> eventProcessingConfigurer .registerSaga(MySaga.class, // Axon defaults to an in-memory SagaStore, // defining another is recommended sagaConfigurer -> sagaConfigurer.configureSagaStore(c -> new JpaSagaStore(...)))); // alternatively, it is possible to register a single SagaStore for all Saga types: configurer.registerComponent(SagaStore.class, c -> new JpaSagaStore(...)); Spring Boot AutoConfiguration@Saga(sagaStore = "mySagaStore") public class MySaga {...} ... // somewhere in configuration @Bean public SagaStore mySagaStore() { return new MongoSagaStore(...); // default is JpaSagaStore }Saga repository 和 saga store SagaRepository 负责存储和检索 saga,供 SagaManager 使用。 它能够通过它们的标识符以及它们的关联值来检索特定的 saga 实例。 但是,有一些特殊要求。 由于 saga 中的并发处理是一个非常微妙的过程,repository 必须确保对于每个概念 saga 实例(具有相同的标识符)在 JVM 中仅存在一个实例。 Axon 提供 AnnotatedSagaRepository 实现,它允许查找 saga 实例,同时保证只能同时访问 saga 的单个实例。 它使用 SagaStore 来执行 saga 实例的实际持久化。 使用的实现选择主要取决于应用程序使用的存储引擎。 Axon 提供了 JdbcSagaStore 、InMemorySagaStore 、JpaSagaStore 和 MongoSagaStore 。 在某些情况下,应用程序受益于缓存 saga 实例。 在这种情况下,有一个 CachingSagaStore 包装了另一个实现以添加缓存行为。 请注意,CachingSagaStore 是直写式缓存,这意味着保存操作始终会立即转发到后备存储,以确保数据安全。JpaSagaStore JpaSagaStore 使用 JPA 来存储 sagas 的状态和关联值。 Sagas 本身不需要任何 JPA 注解; Axon 将使用 Serializer 对 sagas 进行序列化(类似于事件序列化,您可以在 XStreamSerializer 或 JacksonSerializer 之间进行选择,可以通过在应用程序中配置默认的 Serializer 来设置。有关更多详细信息,请参阅序列化程序 . JpaSagaStore 配置有 EntityManagerProvider ,它提供对要使用的 EntityManager 实例的访问。 这种抽象允许使用应用程序管理和容器管理的 EntityManager 。 或者,您可以定义序列化程序来序列化 Saga 实例。 Axon 默认为 XStreamSerializer 。JdbcSagaStore JdbcSagaStore 使用纯 JDBC 来存储阶段实例及其关联值。 与 JpaSagaStore 类似,saga 实例不需要知道它们是如何存储的。 存储使用序列化程序序列化 saga 实例。 您应该使用 DataSource 或 ConnectionProvider 配置 JdbcSagaStore 。 虽然不是必需的,但在使用 ConnectionProvider 进行初始化时,建议将实现包装在 UnitOfWorkAwareConnectionProviderWrapper 中。 它将检查当前工作单元中是否存在已打开的数据库连接,以确保工作单元内的所有活动都在单个连接上完成。 与 JPA 不同, JdbcSagaRepository 使用纯 SQL 语句来存储和检索信息。 这种方法可能意味着某些操作依赖于特定于数据库的 SQL 方言。 也可能是某些数据库供应商提供了您想使用的非标准功能。 为此,您可以提供自己的 SagaSqlSchema 。 SagaSqlSchema 是一个接口,它定义了存储库需要在底层数据库上执行的所有操作。 它允许您自定义为每个操作执行的 SQL 语句。 默认值为 GenericSagaSqlSchema 。 其他可用的实现是 PostgresSagaSqlSchema 、Oracle11SagaSqlSchema 和 HsqlSagaSchema 。 Schema 构建 请注意,Axon 不会为您创建开箱即用的数据库 schema 。 例如,在使用 Spring Boot 时也不行。 要构建 schema,应该调用 JdbcSagaStore#createSchema 。 默认情况下,这将使用 GenericSagaSqlSchema 。 您可以通过 JdbcSagaStore.Builder 配置不同的版本来更改 schema。MongoSagaStore MongoSagaStore 将 saga 实例及其关联存储在 MongoDB 数据库中。 MongoSagaStore 将所有 saga 存储在 MongoDB 数据库中的单个集合中。 对于每个 saga 实例,都会创建一个文档。 MongoSagaStore 还确保在任何时候,对于单个 JVM 中的任何唯一 Saga,都只存在一个 Saga 实例。 这可确保不会因并发问题而丢失状态更改。 MongoSagaStore 使用 MongoTemplate 和可选的 Serializer 初始化。 MongoTemplate 提供了对存储 sagas 的集合的引用。Axon 提供了 DefaultMongoTemplate ,它接受一个 MongoClient 实例以及数据库名称和存储 sagas 的集合名称。数据库名称 和集合名称可以省略。 在这种情况下,它们分别默认为 "axonframework" 和 "sagas" 。缓存 如果使用数据库支持的 saga 存储,保存和加载 saga 实例可能是一项相对昂贵的操作。 在短时间内多次调用同一个 saga 实例的情况下,缓存可能对应用程序的性能特别有益。 Axon 提供 CachingSagaStore 实现。 它是一个包装了另一个 SagaStore 的 SagaStore ,它负责实际存储。 加载 saga 或关联值时,CachingSagaStore 将首先查询其缓存,然后再委托给包装的 repository。 存储信息时,所有调用总是被委派以确保后备存储始终对 saga 的状态有一致的视图。 要配置缓存,只需将任何 SagaStore 包装在 CachingSagaStore 中。 CachingSagaStore 的构造函数采用三个参数: 1. 要包装的 SagaStore 2. 用于关联值的缓存 3. 用于 saga 实例的缓存 后两个参数可能指的是同一个缓存,也可能指不同的缓存。 这取决于您的特定应用程序的要求。