如何在Axon EventStore中存储事件?

时间:2020-11-12 16:39:10

标签: spring cqrs axon

以下示例使用Axon使用spring实现事件源(和CQRS)。

https://github.com/dashsaurabh/event-sourcing-cqrs-axon-spring-boot

有关代码的文章:

http://progressivecoder.com/event-sourcing-and-cqrs-with-axon-and-spring-boot-part-2//

在应用程序中:

  • 一个 JPA存储库存储实体的实际状态
  • 事件存储在单独的 EventStore 中。

我很难理解示例中的事件如何存储在EventStore中。在 AccountQueryServiceImpl 中,创建了一个 EventStore ,并用于读取事件。但是EventStore如何准确填充? (服务类由REST端点调用)

关于JPA存储库 accountRepository ,只要BaseEvent为,通过使用 AccountQueryEntityManager 中的 save()方法就可以保留一个新帐户。被解雇了,但我找不到在EventStore后面追加内容的代码行。

AccountQueryServiceimpl

@Service
public class AccountQueryServiceImpl implements AccountQueryService {

private final EventStore eventStore;

private final AccountRepository accountRepository;

public AccountQueryServiceImpl(EventStore eventStore, AccountRepository 
accountRepository) {
    this.eventStore = eventStore;
    this.accountRepository = accountRepository;
}

@Override
public List<Object> listEventsForAccount(String accountNumber) {
    return eventStore.readEvents(accountNumber).asStream().map( s -> 
s.getPayload()).collect(Collectors.toList());
}

@Override
public AccountQueryEntity getAccount(String accountNumber) {
    return accountRepository.findById(accountNumber).get();
}
}

AccountQueryEntityManager

@Component
public class AccountQueryEntityManager {

@Autowired
private AccountRepository accountRepository;

@Autowired
@Qualifier("accountAggregateEventSourcingRepository")
private EventSourcingRepository<AccountAggregate> accountAggregateEventSourcingRepository;

@EventSourcingHandler
void on(BaseEvent event){
persistAccount(buildQueryAccount(getAccountFromEvent(event)));
}


private AccountAggregate getAccountFromEvent(BaseEvent event){
return accountAggregateEventSourcingRepository.load(event.id.toString()).getWrappedAggregate().getAggregateRoot();
}

private AccountQueryEntity findExistingOrCreateQueryAccount(String id){
return accountRepository.findById(id).isPresent() ? accountRepository.findById(id).get() : new AccountQueryEntity();
}

private AccountQueryEntity buildQueryAccount(AccountAggregate accountAggregate){
AccountQueryEntity accountQueryEntity =     findExistingOrCreateQueryAccount(accountAggregate.getId());

accountQueryEntity.setId(accountAggregate.getId());
accountQueryEntity.setAccountBalance(accountAggregate.getAccountBalance());
accountQueryEntity.setCurrency(accountAggregate.getCurrency());
accountQueryEntity.setStatus(accountAggregate.getStatus());

return accountQueryEntity;
}

private void persistAccount(AccountQueryEntity accountQueryEntity){
accountRepository.save(accountQueryEntity);
}
}

1 个答案:

答案 0 :(得分:2)

Axon Framework旨在为您提供轻松的构建基块,以与DDD,CQRS和事件源一起使用。通过这种方式,开箱即用提供了许多管道,使您在那条路上的生活尽可能轻松。

要了解这是如何工作的,值得注意的是假设共享样本集中在所有三个范例上。在这种情况下,您可以将“事件”用作应用程序的“命令”和“查询”端之间的同步手段(通常以不同模型的形式)。

应用程序的Command端将通过处理命令并验证其自身状态来处理业务验证。结果,将发布一个事件。在典型的Axon应用程序中,这是在聚合的生命周期内发生的。为了让框架用户要求直接连接EventStoreEventBus,并增加了确保事件以正确顺序存储的所有复杂性,Axon提供了AggregateLifecycle#apply(Object)方法。

通过这种方式,框架将能够自动找到用于发布事件的EventBus,该事件也将最终出现在EventStore中。

旁注

  • 您所指的示例使用Axon4。由于4.4.4是最近发布的,因此它已经相当老了。如果您尝试一下,请使用更新的示例作为指导,例如AxonIQ的Hotel Demo
  • 您想知道的任何其他详细信息在Reference Guide中都有详细记录。如果您需要进一步研究,我强烈建议您将导板保持在打开状态。
  • 还有一些在线视频可以帮助您开始使用Axon。对于那些偏爱视频而非文字的人,请访问this YouTube频道。 This系列是一个实际的快速入门,这可能也会有所帮助。