30.Axon框架-查询

23 阅读2分钟

查询

1.介绍

查询消息(Query Message),简称查询(Queries)。这类消息的核心作用是请求特定格式的信息。任何组件都可声明自身能够处理某类查询消息,并为其提供响应

2.处理器

介绍

查询的处理核心是通过标注@QueryHandler的方法返回查询响应

QueryHandler是DDD+CQRS中查询侧(Query Side)的核心组件,负责封装只读数据获取逻辑,完全贴合 Query 管读取、无副作用的铁律,其操作对象通常是DDD中的查询模型(Query Model)(如投影Projection),而非领域模型的聚合根

使用

步骤
  1. 定义查询消息
  2. 编写QueryHandler
  3. 通过QueryGateway或QueryBus发送查询消息
定义查询消息

1768804621508.png

编写QueryHandler

1768804680507.png

通过QueryGateway或QueryBus发送查询消息

调用QueryGateway.query()即可

组成

1768818085128.png

SpringBoot环境下注册

1768818165273.png

调用顺序

1768804903007.png

链式调用

介绍

某个QueryHandler依赖另一个QueryHandler的某个查询的结果,可在当前QueryHandler中调用QueryGateway或QueryBus。但需谨慎使用,这种方式会创建两个QueryHandler的依赖关系,可能导致耦合或死锁风险,违背DDD查询模型独立的设计原则

本地调用与远程调用

1768807014674.png

避免死锁

1768807149425.png

1768807201594.png

返回值

支持的类型

1768808002171.png

1768808013291.png

不支持的类型

1768808331270.png

3.调度

介绍

1768810723018.png

分发模式/查询策略

1768804192776.png

点对点查询

1768811282464.png

分散与聚合查询

1768811378872.png

注意:

  • 获取所有匹配QueryHandler的响应,最终返回一个Stream
  • Stream中顺序不固定
  • 无匹配QueryHandler或所有QueryHandler处理失败时,返回空Stream

订阅式查询

省略。。。底层基于响应式编程框架reactor,等作者学了的

流式查询

省略。。。底层基于响应式编程框架reactor,等作者学了的

4.QueryGateway与QueryBus

介绍

1768810848919.png

分发模式的支持

无论选择QueryBus还是QueryGateway,两者均支持四种分发模式:

  • 点对点查询
  • 分散聚合查询
  • 订阅式查询
  • 流式查询

QueryGateway

介绍

查询网关是查询调度机制的便捷封装接口,并非强制使用,但却是最推荐的查询调度方式,它大幅降低了开发者的使用成本,屏蔽了底层复杂细节

默认实现

Axon 提供QueryGateway接口及默认实现DefaultQueryGateway

核心能力
  • 支持同步、带超时、异步三种查询方式
  • 可获取单个或多个查询结果
可配置项
  • QueryBus
  • QueryDispatchInterceptor

QueryBus

介绍

1768817527357.png

实现
  • AxonServerQueryBus
  • SimpleQueryBus
AxonServerQueryBus

1768817662375.png

SimpleQueryBus

1768817837908.png

SpringBoot环境的配置方式如下:

@Configuration
public class AxonConfig {
    // omitting other configuration methods...
    @Bean
    public QueryBus queryBus(GlobalMetricRegistry metricRegistry,
                             SpanFactory spanFactory,
                             TransactionManager transactionManager,
                             QueryUpdateEmitter updateEmitter) {
        return SimpleQueryBus.builder()
                             .messageMonitor(metricRegistry.registerQueryBus("queryBus"))
                             .transactionManager(transactionManager)
                             .spanFactory(spanFactory)
                             .queryUpdateEmitter(updateEmitter)
                             // ..
                             .build();
    }
}