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

你这是什么意思? 我怀疑您正在体验聚合的事件源部分。

基本上,你的流程应该是这样的:

  1. IssueCardCommand -> 由 Aggregate 处理,有效地为您创建一个并应用随后的 CardIssuedEvent,它将立即由您的 EventSourcingHandler 处理。
  2. ReimburseCardCommand -> 您的 Aggregate 是根据过去重建的(事件源),这意味着所有 @EventSourcingHandler 将在命令处理程序之前被调用。当 Aggregate 与事件同步时,它将根据 @CommandHandler 方法处理您的命令。

obs:似乎您有一个重复的命令处理程序方法,一个在 @Aggregate 上,另一个在 @AggregateMember 上。我会仔细检查这是否正确,以及你是否在我相信你没有的两个地方都得到了你的命令。