Axon EventHandler 不接收事件
Axon EventHandler does not receive event
我需要有关正确配置 Axon 应用程序的帮助,或者我对 Axon 的理解有误。我有两个聚合:
- "FileStore",存储索引文件的信息
- "DirectoryLister",它为它索引的每个文件发送事件。
我遇到的问题是 "DirectoryLister" 使用
发送事件
AggregateLifecycle.apply(new IndexedFileEvent(...));
在 "DirectoryLister" 中,我能够在 EventSourcingHandler 中捕获事件。但是在 "FileStore" then 事件处理程序内部没有反应。我确认该事件已发布在事件总线上。
我想,我需要使用 "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 class 如下所示:
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" class 看起来像这样:
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());
}
}
如果我没看错,您正在尝试处理从聚合 DirectoryLister
发布到聚合 FileStore
的事件,正确吗?
然而,这个假设本质上是不可能的。
您所描述的聚合本质上是 CQRS 设置中的命令模型。
因此,它 处理来自外界的命令 ,然后决定是否可以在该阶段执行给定的 command/operation。
作为推断是否可以处理命令的结果,发布了一个事件通知 "something has happened"。
然而,命令模型并非旨在直接处理事件。
它处理事件的唯一时间是 "source itself from the change which it has published"。
这就是为什么聚合中的事件处理程序在 Axon 中不是 @EventHandler
,而是 @EventSourcingHandler
,因为它只能 处理来自其自身源的事件。
参考指南还指出,在给定聚合中处理来自其他聚合的事件是不可能的(您可以找到 here)。
所以,简单地说,您所期望的不可能是 Mathias。
您需要在其间放置一个事件处理组件,该组件对来自 DirectoryLister
的给定事件做出反应,并将其转换为您要在 FileStore
.
上执行的命令
我需要有关正确配置 Axon 应用程序的帮助,或者我对 Axon 的理解有误。我有两个聚合:
- "FileStore",存储索引文件的信息
- "DirectoryLister",它为它索引的每个文件发送事件。
我遇到的问题是 "DirectoryLister" 使用
发送事件AggregateLifecycle.apply(new IndexedFileEvent(...));
在 "DirectoryLister" 中,我能够在 EventSourcingHandler 中捕获事件。但是在 "FileStore" then 事件处理程序内部没有反应。我确认该事件已发布在事件总线上。 我想,我需要使用 "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 class 如下所示:
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" class 看起来像这样:
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());
}
}
如果我没看错,您正在尝试处理从聚合 DirectoryLister
发布到聚合 FileStore
的事件,正确吗?
然而,这个假设本质上是不可能的。 您所描述的聚合本质上是 CQRS 设置中的命令模型。 因此,它 处理来自外界的命令 ,然后决定是否可以在该阶段执行给定的 command/operation。 作为推断是否可以处理命令的结果,发布了一个事件通知 "something has happened"。
然而,命令模型并非旨在直接处理事件。
它处理事件的唯一时间是 "source itself from the change which it has published"。
这就是为什么聚合中的事件处理程序在 Axon 中不是 @EventHandler
,而是 @EventSourcingHandler
,因为它只能 处理来自其自身源的事件。
参考指南还指出,在给定聚合中处理来自其他聚合的事件是不可能的(您可以找到 here)。
所以,简单地说,您所期望的不可能是 Mathias。
您需要在其间放置一个事件处理组件,该组件对来自 DirectoryLister
的给定事件做出反应,并将其转换为您要在 FileStore
.