单独的 class Axon 3.0.3 中的事件处理程序

Event handlers in a separate class Axon 3.0.3

我在这里使用 Axon 和 Spring 进行了相当简单的 CQRS 设置。

这是配置class。

@AnnotationDriven
@Configuration
public class AxonConfig {

    @Bean
    public EventStore eventStore() {
        ...
    }

    @Bean
    public CommandBus commandBus() {
        return new SimpleCommandBus();
    }

    @Bean
    public EventBus eventBus() {
        return new SimpleEventBus();
    }
}

这是我的聚合...

@Aggregate
public class ThingAggregate {
    @AggregateIdentifier
    private String id;

    public ThingAggregate() {
    }

    public ThingAggregate(String id) {
        this.id = id;
    }

    @CommandHandler
    public handle(CreateThingCommand cmd) {
        apply(new ThingCreatedEvent('1234', cmd.getThing()));
    }

    @EventSourcingHandler
    public void on(ThingCreatedEvent event) {
        // this is called!
    }
}

这是我在单独的 .java 文件中的事件处理程序...

@Component
public class ThingEventHandler {

    private ThingRepository repository;

    @Autowired
    public ThingEventHandler(ThingRepository thingRepository) {
        this.repository = conditionRepository;
    }

    @EventHandler
    public void handleThingCreatedEvent(ThingCreatedEvent event) {
        // this is only called if I publish directly to the EventBus
        // apply within the Aggregate does not call it!
        repository.save(event.getThing());
    }
}

我正在使用 CommandGateway 发送原始创建命令。我在聚合中的 CommandHandler 可以很好地接收命令,但是当我在我的聚合中调用 apply 并传递一个新事件时,我在外部 class 中的 EventHandler 不会被调用。仅调用直接在聚合 class 内的事件处理程序。

如果我尝试将事件直接发布到 EventBus,则会调用我的外部 EventHandler。

知道为什么当我在聚合中调用 apply 时我在外部 java class 中的事件处理程序没有被调用吗?

在 Axon 3 中,事件存储是事件总线的替代。它基本上是一个专门的实现,不仅将事件转发给订阅者,而且还存储它们。

在您的配置中,您同时拥有事件总线和事件存储。聚合的事件可能已发布到事件存储。由于您在直接发布到事件总线时会在处理程序中收到事件,因此您的处理程序会在那里订阅。

解决方案:从您的配置中删除事件总线并独占使用事件存储。