gpt4 book ai didi

java - 在调用 EventSourcingHandlers 之间如何保留实体的状态?

转载 作者:行者123 更新时间:2023-11-30 05:45:08 24 4
gpt4 key购买 nike

Axon Giftcard demo ,有一个 GiftCard 类,注释为@Aggregate:

@Aggregate
@Profile("command")
public class GiftCard {

private final static Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

@AggregateIdentifier
private String id;
private int remainingValue;

@CommandHandler
public GiftCard(IssueCmd cmd) {
log.debug("handling {}", cmd);
if(cmd.getAmount() <= 0) throw new IllegalArgumentException("amount <= 0");
apply(new IssuedEvt(cmd.getId(), cmd.getAmount(), cmd.getCurrency()));
}

@CommandHandler
public void handle(RedeemCmd cmd) {
log.debug("handling {}", cmd);
if(cmd.getAmount() <= 0) throw new IllegalArgumentException("amount <= 0");
if(cmd.getAmount() > remainingValue) throw new IllegalStateException("amount > remaining value");
apply(new RedeemedEvt(id, cmd.getAmount()));
}

...
@EventSourcingHandler
public void on(IssuedEvt evt) {
log.debug("applying {}", evt);
id = evt.getId();
remainingValue = evt.getAmount();
currency = evt.getCurrency();
log.debug("new remaining value: {}", remainingValue);
log.debug("new currency: {}", currency);
}

@EventSourcingHandler
public void on(RedeemedEvt evt) {
log.debug("applying {}", evt);
remainingValue -= evt.getAmount();
log.debug("new remaining value: {}", remainingValue);
}
...

命令和事件类在 Kotlin 代码中定义:

data class IssueCmd(@TargetAggregateIdentifier val id: String, val amount: Int)
data class IssuedEvt(val id: String, val amount: Int)
data class RedeemCmd(@TargetAggregateIdentifier val id: String, val amount: Int)
data class RedeemedEvt(val id: String, val amount: Int)

假设以下两个命令被放置在命令总线上:

Command #     Command Class   id          amount
--------- ------------- ------- -------------
1 IssueCmd QP34 123.45
2 RedeemCmd QP34 38.10

处理第一个命令时,IssueCmd 的 CommandHandler (CH) 将在事件总线上放置一个 IssuedEvt 对象。该事件将由 IssuedEvt 的 EventSourcingHandler (ESH) 进行处理。然后,我们将拥有一个 GiftCard 实例,其 id 设置为“QP34”,remainingValue 设置为 >123.45

处理第二个命令时,RedeemCmd 的 CH 会将一个 RedeemedEvt 对象放在事件总线上。该事件将由 ESH 处理 RedeeemedEvt。然后,我们将拥有一个 GiftCard 实例,其 id 设置为“QP34”,remainingValue 设置为 >85.35

问题:每个事件由其指定的 ESH 处理后,生成的对象实例如何以及在何处持续存在?

之前,我听到的答案是:确实没有。所有持续存在的都是事件对象,它们保存在 Axon 的事件存储中。当需要对象的当前状态时,Axon 告诉命令模型启动 GiftCard 类的实例,并从最早到最晚的时间对其应用事件。这就是事件溯源的定义。

但是,在事件溯源时,处理 IssuedEvt 后,remainingValue 中的 123.45 必须保留在某处,以便 ESH使 RedeemedEvt 的减法运算具有正确的值。

在调用 ESH 之间如何以及在何处保留对象状态?

最佳答案

框架在内部实例化 AnnotatedAggregate当您检索Aggregate时来自 Repository 的实例.

AnnotatedAggregate类实现 Aggregate ,其中Repository接口(interface)强制为 load(String) 上的返回类型操作。

当您谈论事件溯源时,Repository正在使用的实现是 EventSourcingRepository ,在load(String)上返回 EventSourcedAggregate实例(这是 AnnotatedAggregate 的实现。

Aggregate接口(interface),AnnotatedAggregate该接口(interface)和 EventSourcedAggregate 的实现再次实现它,定义一个泛型。

此泛型是的聚合实现。

当您通过EventSourcingRepository对聚合进行事件溯源时,您的聚合实例保存在 AnnotatedAggregate内存中下private T aggregateRoot全局领域。

这个aggregateRootEventSourcingRepository 更新,它初始化 EventSourcedAggregate 的状态通过给它一个 EventMessages 的流.

顺便问一下,@JonathanM,你为什么对这一点感兴趣?

以下是这些类的 GitHub 链接,供引用:

  1. Aggregate
  2. AnnotatedAggregate
  3. EventSourcedAggregate
  4. Repository
  5. EventSourcingRepository

关于java - 在调用 EventSourcingHandlers 之间如何保留实体的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54988020/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com