Axon 使用无参数构造函数隐式实例化另一个聚合
Axon implicitly instantiate another aggregate using paramless constructor
我只是想知道为什么 Axon 隐式实例化另一个聚合。此行为会导致多个事件处理,我认为这种开销不是预期的。
具有此端点:
@PostMapping("ship")
public void shipOrder(@RequestBody Product product) {
String orderId = UUID.randomUUID().toString();
commandGateway.sendAndWait(new PlaceOrderCommand(orderId, product.getName()));
commandGateway.sendAndWait(new ConfirmOrderCommand(orderId));
}
和以下合计:
@Aggregate
public class Order {
@AggregateIdentifier
private String orderId;
private boolean orderConfirmed;
@CommandHandler
public Order(PlaceOrderCommand command) {
System.out.println("Calling COMMAND constructor");
apply(new OrderPlacedEvent(command.getOrderId(), command.getProduct()));
}
protected Order() {
System.out.println("Calling PARAMLESS constructor");
}
@CommandHandler
public void handle(ConfirmOrderCommand command) {
apply(new OrderConfirmedEvent(command.getOrderId()));
}
@EventSourcingHandler
public void on(OrderPlacedEvent event) {
System.out.println(">>>>>> Handling OrderPlacedEvent: " + this);
this.orderId = event.getOrderId();
orderConfirmed = false;
}
@EventSourcingHandler
public void on(OrderConfirmedEvent event) {
System.out.println(">>>>>> Handling OrderConfirmedEvent: " + this);
orderConfirmed = true;
}
}
在我收到此日志后调用端点后:
Calling COMMAND constructor
>>>>>> Handling OrderPlacedEvent: Order@3eecb9e2
Calling PARAMLESS constructor
>>>>>> Handling OrderPlacedEvent: Order@cd10277
>>>>>> Handling OrderConfirmedEvent: Order@cd10277
如您所见,OrderPlacedEvent 被调用了两次,连同不带参数的构造函数。有人知道我为什么会出现以下行为吗?
当您使用事件溯源时,这种行为是正确的并且是预期的。在事件溯源中,每当您向聚合发送命令时,它都会首先加载所有先前的事件以补充聚合并确定其当前状态。这些事件是您的真实来源。除了一些例外,聚合的当前状态未被存储。
因此,一般来说,您应该确保只在聚合中使用 EventSourcingHandler
来填充其状态。
请注意,一旦系统增长很多,聚合可能会包含大量需要读取的事件。如果发生这种情况,您可以通过在每个 n
事件后存储聚合快照(当前状态)来进行一些优化。这样您就不必加载超过 n
个事件。
我只是想知道为什么 Axon 隐式实例化另一个聚合。此行为会导致多个事件处理,我认为这种开销不是预期的。 具有此端点:
@PostMapping("ship")
public void shipOrder(@RequestBody Product product) {
String orderId = UUID.randomUUID().toString();
commandGateway.sendAndWait(new PlaceOrderCommand(orderId, product.getName()));
commandGateway.sendAndWait(new ConfirmOrderCommand(orderId));
}
和以下合计:
@Aggregate
public class Order {
@AggregateIdentifier
private String orderId;
private boolean orderConfirmed;
@CommandHandler
public Order(PlaceOrderCommand command) {
System.out.println("Calling COMMAND constructor");
apply(new OrderPlacedEvent(command.getOrderId(), command.getProduct()));
}
protected Order() {
System.out.println("Calling PARAMLESS constructor");
}
@CommandHandler
public void handle(ConfirmOrderCommand command) {
apply(new OrderConfirmedEvent(command.getOrderId()));
}
@EventSourcingHandler
public void on(OrderPlacedEvent event) {
System.out.println(">>>>>> Handling OrderPlacedEvent: " + this);
this.orderId = event.getOrderId();
orderConfirmed = false;
}
@EventSourcingHandler
public void on(OrderConfirmedEvent event) {
System.out.println(">>>>>> Handling OrderConfirmedEvent: " + this);
orderConfirmed = true;
}
}
在我收到此日志后调用端点后:
Calling COMMAND constructor
>>>>>> Handling OrderPlacedEvent: Order@3eecb9e2
Calling PARAMLESS constructor
>>>>>> Handling OrderPlacedEvent: Order@cd10277
>>>>>> Handling OrderConfirmedEvent: Order@cd10277
如您所见,OrderPlacedEvent 被调用了两次,连同不带参数的构造函数。有人知道我为什么会出现以下行为吗?
当您使用事件溯源时,这种行为是正确的并且是预期的。在事件溯源中,每当您向聚合发送命令时,它都会首先加载所有先前的事件以补充聚合并确定其当前状态。这些事件是您的真实来源。除了一些例外,聚合的当前状态未被存储。
因此,一般来说,您应该确保只在聚合中使用 EventSourcingHandler
来填充其状态。
请注意,一旦系统增长很多,聚合可能会包含大量需要读取的事件。如果发生这种情况,您可以通过在每个 n
事件后存储聚合快照(当前状态)来进行一些优化。这样您就不必加载超过 n
个事件。