【问题标题】:Axon EventHandler does not receive eventAxon EventHandler 没有收到事件
【发布时间】:2020-01-13 08:50:29
【问题描述】:

我需要正确配置 Axon 应用程序的帮助,或者我对 axon 的理解是错误的。我有两个聚合:

  • “FileStore”,存储索引文件的信息
  • “DirectoryLister”,它为它索引的每个文件发送事件。

我遇到的问题是“DirectoryLister”使用

发送事件
AggregateLifecycle.apply(new IndexedFileEvent(...)); 

在“DirectoryLister”中,我可以在 EventSourcingHandler 中捕获事件。但是在“FileStore”内部,事件处理程序没有反应。我验证了事件已在事件总线上发布。 我想,我需要使用“AnnotationEventListenerAdapter”以某种方式让 FileStore 在事件总线上监听,但是我找不到一个没有 spring 的例子来说明它是如何工作的。

我正在使用没有 Spring 的 Axon 3.4.3 并像这样配置应用程序:

    Configurer configer = DefaultConfigurer.defaultConfiguration();
    configer.configureEmbeddedEventStore(c -> new InMemoryEventStorageEngine());
    // configure two Aggregates
    configer.configureAggregate(FileStore.class);
    configer.configureAggregate(DirectoryLister.class);

    // how can I register FileStore as an eventListener? Using AnnotationEventListenerAdapter?

    Configuration config = configer.buildConfiguration();

    // verify that event is published on the event bus
    config.eventBus().subscribe(l -> l.forEach( e -> System.out.println(e.toString())));
    config.start();

FileStore 类如下所示:

public class FileStore {
    @AggregateIdentifier String id; 

    public FileStore() { }

    @CommandHandler public FileStore(CreateFileStoreCommand command) {
        AggregateLifecycle.apply(new FileStoreCreatedEvent(command.getId()));
    }

    @EventSourcingHandler public void on(FileStoreCreatedEvent event) {
        id = event.getId();
    }

    @EventSourcingHandler public void on(IndexedFileEvent event) {
        System.out.println(event.getParentPath() + "//" + event.getName() + "  " + event.getSize().toString());
    }

“DirectoryLister”类如下所示:

  public class DirectoryLister {
    @AggregateIdentifier String id; 

    protected  DirectoryLister() { }

    @CommandHandler public DirectoryLister(CreateListerCommand cmd) {
        AggregateLifecycle.apply(new CreateListerEvent(cmd.getId()));   
    }

    @CommandHandler public void handleCommand(IndexDirectoryCommand cmd) throws IOException {
         FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
              @Override
              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                // this is where the event is sent!
                AggregateLifecycle.apply(new IndexedFileEvent(file.getFileName().toString(),file.getParent().toString(), attrs.size())); 
                return FileVisitResult.CONTINUE;
              }
            };

          Files.walkFileTree(cmd.getPath(), fv);
    }

    @EventSourcingHandler public void on (CreateListerEvent event) { id = event.getId(); }

    // This handler is invoked. 
    @EventSourcingHandler public void on(IndexedFileEvent event) {
        System.out.println(event.getParentPath() + "//" + event.getName() + "  " + event.getSize().toString());
    }
}

【问题讨论】:

    标签: java event-bus axon


    【解决方案1】:

    如果我的理解正确,您正在尝试处理从 Aggregate DirectoryLister 发布到 Aggregate FileStore 的事件,对吗?

    但是,这种假设本质上是不可能的。 您描述的聚合本质上是 CQRS 设置中的命令模型。 因此,它处理来自外部世界的命令,然后决定是否可以在该阶段执行给定的命令/操作。 作为推断是否可以处理命令的结果,发布事件通知“发生了某事”。

    然而,命令模型旨在直接处理事件。 它处理事件的唯一时间是“从它发布的更改中获取自身”。 这就是为什么聚合中的事件处理程序不是 Axon 中的 @EventHandler,而是 @EventSourcingHandler,因为它只能处理来自其自身来源的事件。

    参考指南还指出,在给定聚合中处理来自其他聚合的事件是不可能的(您可以找到here)。

    所以,简单地说,你所期望的不可能是 Mathias。 您需要在其间放置一个事件处理组件,该组件对来自DirectoryLister 的给定事件做出反应,并将其转换为您要在FileStore 上执行的命令。

    【讨论】:

      猜你喜欢
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多