在聚合篇中,我们看到了如何创建由事件溯源支持的聚合。换句话说,事件溯源聚合的存储方法是通过重放构成聚合变化的事件。 然而,聚合也可以按原样存储。这样做时,用于保存和加载聚合的Repository是GenericJpaRepository。聚合状态存储的结构与事件溯源聚合有点不同:importorg。axonframework。commandhandling。CommandHandler;importorg。axonframework。eventhandling。EventHandler;importorg。axonframework。modelling。command。AggregateIdentifier;importorg。axonframework。modelling。command。AggregateMember;importjavax。persistence。CascadeType;importjavax。persistence。Entity;importjavax。persistence。FetchType;importjavax。persistence。Id;importjavax。persistence。JoinColumn;importjavax。persistence。OneToMany;Entity1。publicclassGiftCard{Id2。AggregateIdentifierprivateStringid;3。OneToMany(fetchFetchType。EAGER,cascadeCascadeType。ALL)JoinColumn(namegiftCardId)AggregateMemberprivateListGiftCardTransactiontransactionsnewArrayList();privateintremainingValue;CommandHandler4。publicGiftCard(IssueCardCommandcmd){if(cmd。getAmount()0){thrownewIllegalArgumentException(amount0);}idcmd。getCardId();remainingValuecmd。getAmount();5。apply(newCardIssuedEvent(cmd。getCardId(),cmd。getAmount()));}CommandHandlerpublicvoidhandle(RedeemCardCommandcmd){6。if(cmd。getAmount()0){thrownewIllegalArgumentException(amount0);}if(cmd。getAmount()remainingValue){thrownewIllegalStateException(amountremainingvalue);}if(transactions。stream()。map(GiftCardTransaction::getTransactionId)。anyMatch(cmd。getTransactionId()::equals)){thrownewIllegalStateException(TransactionIdmustbeunique);}7。remainingValuecmd。getAmount();transactions。add(newGiftCardTransaction(id,cmd。getTransactionId(),cmd。getAmount()));apply(newCardRedeemedEvent(id,cmd。getTransactionId(),cmd。getAmount()));}EventHandler8。protectedvoidon(CardReimbursedEventevent){this。remainingValueevent。getAmount();}protectedGiftCard(){}9。} 上面的摘录显示了来自GiftCardService的状态存储聚合。片段中的编号注释指出了Axon的细节,在此解释:由于聚合存储在JPA存储库中,因此需要使用Entity注解类。聚合根必须声明一个包含聚合标识符的字段。 此标识符最迟必须在第一个事件发布时初始化。 此标识符字段必须由AggregateIdentifier注解进行注解。 当使用JPA存储Aggregate时,Axon知道使用JPA提供的Id注解。 由于Aggregate是一个实体,Id注解是一个硬性要求。这个聚合有几个AggregateMembers。 由于聚合按原样存储,因此应考虑实体的正确映射。带CommandHandler注解的构造函数,或者以不同的方式放置commandhandlingconstructor。 此注解告诉框架给定的构造函数能够处理IssueCardCommand。静态的AggregateLifecycleapply(Object)可用于发布EventMessage。 调用此函数后,提供的Object将在应用它们的聚合范围内作为EventMessage发布。命令处理方法将首先决定此时传入的命令是否有效处理。业务逻辑验证后,可以调整聚合的状态Aggregate中的实体可以通过定义EventHandler注解方法来监听Aggregate发布的事件。 当事件消息在被任何外部处理程序处理之前发布时,将调用这些方法。JPA需要的无参数构造函数。 未能提供此构造函数将在加载聚合时导致异常。 在命令处理程序中调整状态 与事件溯源聚合不同,状态存储聚合可以在命令处理程序中配对决策逻辑和状态更改。遵循这种范式对状态存储聚合没有任何后果,因为没有事件溯源处理程序驱动它的状态。