所以我正在开发我的第一个Axon应用程序。到目前为止,我使整个轴突项目都在整体中工作。之后,我开始使用Sprint Boot中的@Profile将应用程序划分为多个部分。也像魅力一样。因此,我的下一步是完全分发并为Axon流使用2个完全不同的intellij项目。在这里,我遇到了一个问题。我将AMQP用于事件的消息传递。利用文档中的信息,我可以从一个服务到另一个服务获取事件。但是不会触发事件处理程序。我猜问题出在事件的类型上。第一个服务发送事件的方式如下:com.departureExample.Departure.coreapi.events.CheckIn.CheckedInEvent。但是我在其他项目中的事件处理程序会监听:com.checkInService.CheckIn.Service.coreapi.events.CheckIn.CheckedInEvent。我的猜测是这就是为什么未触发事件处理程序,但我不确定的原因?
amqp的所有其他配置均已正确设置,我也将ampqmessagesource连接到我的processingroup。
所以,我的问题是,由于checkedInEvent获得了2条不同的路径,因此事件处理程序是否可能未触发?如果是这样,我该如何解决?
您的假设确实是正确的。您的EventHandler的有效负载类型与发出的事件不匹配。您的EventHandler方法注册为可以处理com.departureExample.Departure.coreapi.events.CheckIn.CheckedInEvent类型的事件。但是,通过Rabbit发送的事件的类型为[[com.departureExample.Departure.coreapi.events.CheckIn.CheckedInEvent,该事件没有注册处理程序。
对于任何EventHandler,要求(super)类与发出的内容匹配,其中包括程序包名称。可以在文档(https://docs.axoniq.io/reference-guide/implementing-domain-logic/event-handling/handling-events)中找到一些更详细的说明:在所有情况下,每个侦听器实例最多调用一个事件处理程序方法。 Axon将使用以下规则搜索最具体的调用方法:
- 在类层次结构的实际实例级别上(由this.getClass()返回),将评估所有带注释的方法
- 如果找到一个或多个可以将所有参数解析为值的方法,则将选择并调用具有最特定类型的方法
- 如果在类层次结构的此级别上未找到任何方法,则以相同的方式评估超级类型
- 当到达层次结构的顶层,并且找不到合适的事件处理程序时,将忽略该事件。
我的建议是使用发出事件的服务的标准名称,在您的情况下为
com.departureExample.Departure.coreapi.events.CheckIn.CheckedInEvent
。即使处理事件的服务位于不同的绑定上下文中,您仍在处理属于发出该事件的绑定上下文的事件。使您的包结构反映出您的代码更具可读性。在这种情况下,消息是应用程序之间的公共API。由于是公开的,它可以/应该在存储库之间作为“核心API”模块/程序包共享。
将事件格式(也称为实现)复制到两个项目中,但是就像您已经说过的那样,这是一个相当草率的解决方案。我想共享专用的Core API模块会更好地为您服务。
如果不想在共享库中共享此“隐式模式”(又名事件的实现),则可以在框架中调整Serializer
以将别名用作类名。
您可以提供给XStream
的XStreamSerializer
实例为别名提供了很好的句柄,使用JacksonSerializer
,您将不得不稍微使用ObjectMapper
。