Axon Command 传递给 EventHandler
Axon Command is delivered to EventHandler
我正在尝试将 Command
发送到 Aggregate
。当我将 Command
发送到 Aggregate
时,聚合的 EventHandler
方法在 CommandHanlder
方法之前被调用。
我不知道这是怎么可能的,因为我只想调用 CommandHandler
方法。
首先我发送 IssueCardCommand
来创建 GiftCard Aggregate
并发送 ReimburseCardCommand
来调用 AggregateMember 的 CommandHandler
方法。
@Autowired
CommandGateway cm;
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
String cardId = UUID.randomUUID().toString();
int transactionValue = (int) (Math.random() * 100);
cm.sendAndWait(new IssueCardCommand(cardId, transactionValue));
cm.sendAndWait(new ReimburseCardCommand(cardId, transactionValue));
};
}
这是我要调用的 GiftCardTransaction
(聚合的子实体)CommandHandler
方法
@CommandHandler
public void handle(ReimburseCardCommand cmd) {
log.info("GiftCardTransaction Handler " + transactionId);
log.info(reimbursed);
// if (reimbursed) {
// throw new IllegalStateException("Transaction already reimbursed");
// }
apply(new CardReimbursedEvent(cmd.getTransactionId(), transactionId, transactionValue));
}
这是Aggregate
@Log4j2
@Aggregate
@NoArgsConstructor
public class GiftCard {
@AggregateIdentifier
private String id;
@AggregateMember(routingKey = "transactionId", eventForwardingMode = ForwardMatchingInstances.class)
private List<GiftCardTransaction> transactions = new ArrayList<>();
private int remainingValue;
@CommandHandler
public GiftCard(IssueCardCommand cmd) {
log.info("GiftCard is created");
apply(new CardIssuedEvent(cmd.getCardId(), cmd.getAmount()));
}
@EventSourcingHandler // 4.
public void on(CardIssuedEvent evt) {
id = evt.getCardId();
remainingValue=evt.getAmount();
log.info(id);
transactions.add(new GiftCardTransaction(id,remainingValue));
String cardId = UUID.randomUUID().toString();
apply(new CardReimbursedEvent(cardId,id,evt.getAmount()));
}
@CommandHandler
public void handle(ReimburseCardCommand cmd) {
String cardId = UUID.randomUUID().toString();
apply(new CardReimbursedEvent(cardId,id,cmd.getTransactionValue()));
}
}
当你说
Aggregate's EventHandler method is invoked before the CommandHanlder method
你这是什么意思?
我怀疑您正在体验聚合的事件源部分。
基本上,你的流程应该是这样的:
IssueCardCommand
-> 由 Aggregate
处理,有效地为您创建一个并应用随后的 CardIssuedEvent
,它将立即由您的 EventSourcingHandler
处理。
ReimburseCardCommand
-> 您的 Aggregate
是根据过去重建的(事件源),这意味着所有 @EventSourcingHandler
将在命令处理程序之前被调用。当 Aggregate
与事件同步时,它将根据 @CommandHandler
方法处理您的命令。
obs:似乎您有一个重复的命令处理程序方法,一个在 @Aggregate
上,另一个在 @AggregateMember
上。我会仔细检查这是否正确,以及你是否在我相信你没有的两个地方都得到了你的命令。
我正在尝试将 Command
发送到 Aggregate
。当我将 Command
发送到 Aggregate
时,聚合的 EventHandler
方法在 CommandHanlder
方法之前被调用。
我不知道这是怎么可能的,因为我只想调用 CommandHandler
方法。
首先我发送 IssueCardCommand
来创建 GiftCard Aggregate
并发送 ReimburseCardCommand
来调用 AggregateMember 的 CommandHandler
方法。
@Autowired
CommandGateway cm;
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
String cardId = UUID.randomUUID().toString();
int transactionValue = (int) (Math.random() * 100);
cm.sendAndWait(new IssueCardCommand(cardId, transactionValue));
cm.sendAndWait(new ReimburseCardCommand(cardId, transactionValue));
};
}
这是我要调用的 GiftCardTransaction
(聚合的子实体)CommandHandler
方法
@CommandHandler
public void handle(ReimburseCardCommand cmd) {
log.info("GiftCardTransaction Handler " + transactionId);
log.info(reimbursed);
// if (reimbursed) {
// throw new IllegalStateException("Transaction already reimbursed");
// }
apply(new CardReimbursedEvent(cmd.getTransactionId(), transactionId, transactionValue));
}
这是Aggregate
@Log4j2
@Aggregate
@NoArgsConstructor
public class GiftCard {
@AggregateIdentifier
private String id;
@AggregateMember(routingKey = "transactionId", eventForwardingMode = ForwardMatchingInstances.class)
private List<GiftCardTransaction> transactions = new ArrayList<>();
private int remainingValue;
@CommandHandler
public GiftCard(IssueCardCommand cmd) {
log.info("GiftCard is created");
apply(new CardIssuedEvent(cmd.getCardId(), cmd.getAmount()));
}
@EventSourcingHandler // 4.
public void on(CardIssuedEvent evt) {
id = evt.getCardId();
remainingValue=evt.getAmount();
log.info(id);
transactions.add(new GiftCardTransaction(id,remainingValue));
String cardId = UUID.randomUUID().toString();
apply(new CardReimbursedEvent(cardId,id,evt.getAmount()));
}
@CommandHandler
public void handle(ReimburseCardCommand cmd) {
String cardId = UUID.randomUUID().toString();
apply(new CardReimbursedEvent(cardId,id,cmd.getTransactionValue()));
}
}
当你说
Aggregate's EventHandler method is invoked before the CommandHanlder method
你这是什么意思? 我怀疑您正在体验聚合的事件源部分。
基本上,你的流程应该是这样的:
IssueCardCommand
-> 由Aggregate
处理,有效地为您创建一个并应用随后的CardIssuedEvent
,它将立即由您的EventSourcingHandler
处理。ReimburseCardCommand
-> 您的Aggregate
是根据过去重建的(事件源),这意味着所有@EventSourcingHandler
将在命令处理程序之前被调用。当Aggregate
与事件同步时,它将根据@CommandHandler
方法处理您的命令。
obs:似乎您有一个重复的命令处理程序方法,一个在 @Aggregate
上,另一个在 @AggregateMember
上。我会仔细检查这是否正确,以及你是否在我相信你没有的两个地方都得到了你的命令。