事件侦听器是对传入事件起作用的组件。 他们通常根据命令模型所做的决定来执行逻辑。 通常,这涉及更新视图模型或将更新转发到其他组件,例如与第三方集成的组件。 在某些情况下,事件处理程序会根据事件的(模式)自己抛出事件,或者甚至发送命令来触发
定义事件处理程序
在Axon中,一个对象可以用@EventHandler注释来声明一些EventHandler方法。该方法的声明参数定义了它将接收哪些事件。
Axon为以下参数类型提供开箱即用的支持:
当使用Spring并且激活AxonConfiguration时(通过包含Axon Spring Boot Starter模块或者在@Configuration类中使用@EnableAxon注解),则任何其他参数都将解析为依赖注入的Bean。 这使您可以将资源直接注入到@EventHandler注解的方法中。
您可以通过实现ParameterResolverFactory接口并创建一个名为/META-INF/service/org.axonframework.common.annotation.ParameterResolverFactory的文件来配置其他ParameterResolver,该文件包含实现类的完全限定名。 详情请参阅高级自定义设置。
在任何情况下,每个侦听器实例最多调用一个事件处理方法。 Axon将使用以下规则搜索最具体的事件处理方法:
//假设EventB extends EventA
//并且EventC extends EventB
//并且 SubListener 是单例
public class TopListener{
@EventHandler
public void handle(EventA event){
}
@EventHandler
public void handle(EventC event){
}
}
public class SubListener extends TopListener{
@EventHandler
public void handle(EventB event){
}
}
在上面的例子中,SubListener的处理程序方法将针对EventB的所有实例以及EventC(因为它扩展了EventB)而被调用。 换句话说,TopListener的处理程序方法根本不会收到EventC的任何调用。 由于EventA不可分配给EventB(它是它的父类),因此事件将由TopListener中的处理程序方法处理。
注册事件处理程序
事件处理组件是使用EventHandlingConfiguration类定义的,该类被注册为全局Axon配置器的模块。 通常,应用程序将定义一个EventHandlingConfiguration,但更大的模块化应用程序可能会选择为每个模块定义一个。
要使用@EventHandler方法注册对象,请在EventHandlingConfiguration上使用registerEventHandler方法:
// define an EventHandlingConfiguration
EventHandlingConfiguration ehConfiguration = new EventHandlingConfiguration().registerEventHandler(conf -> new MyEventHandlerClass());
// the module needs to be registered with the Axon Configuration
Configurer axonConfigurer = DefaultConfigurer.defaultConfiguration().registerModule(ehConfiguration);
有关使用SpringAutoConfiguration注册事件处理程序的详细信息,请参阅事件处理配置章节。
查询处理
查询处理组件作用于传入的查询消息。 他们通常从Event监听器创建的视图模型中读取数据。 查询处理组件通常不会引发新事件或发送命令。
在Axon中,对象可以用@QueryHandler注解它们来声明多个QueryHandler方法。该方法的声明参数定义了它将接收哪些消息。
默认情况下,@QueryHandler注释的方法允许使用以下参数类型:
您可以通过实现ParameterResolverFactory接口并创建一个名为/META-INF/service/org.axonframework.common.annotation.ParameterResolverFactory的文件来配置其他ParameterResolver,该文件包含实现类的完全限定名。 详情请参阅高级自定义设置章节。
在任何情况下,每个查询处理实例至多会调用一个查询处理程序方法。 Axon将使用以下规则查找最具体的调用方法:
请注意,与命令处理类似,与事件处理不同,查询处理不考虑查询消息的类层次结构。
//假设QueryB extends QueryA
//并且QueryC extends QueryB
//并且SubHandler是单例
public class TopHandler{
@QueryHandler
public MyResulthandle(QueryA query){
}
@QueryHandler
public MyResulthandle(QueryB query){
}
@QueryHandler
public MyResulthandle(QueryC query){
}
}
public class SubHandler extends TopHandler{
@QueryHandler
public MyResulthandleEx(QueryB query){
}
}
在上面的例子中,将调用SubHandler的处理方法来查询QueryB和结果MyResult;对QueryA和QueryC的查询和结果MyResult调用TopHandler的处理程序方法。
注册查询处理程序
可以为相同的查询名称和响应类型注册多个查询处理程序。 当分派查询时,客户可以指示他是想要一个结果还是来自所有可用的查询处理程序。
使用Spring
当使用SpringAutoConfiguration时,所有singleton Spring bean都会被扫描以查找具有@QueryHandler批注的方法。 对于找到的每个方法,都会在查询总线中注册一个新的查询处理程序。
使用配置API
也可以使用配置API来注册查询处理程序。 为此,请在Configurer类上使用registerQueryHandler方法:
// Sample query handler
public class MyQueryHandler{
@QueryHandler
public Stringecho(String echo){
return echo;
}
}
// To register yourquery handler
Configurer axonConfigurer =DefaultConfigurer.defaultConfiguration().registerQueryHandler(conf-> new MyQueryHandler);