以下示例使用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//
在应用程序中:
我很难理解示例中的事件如何存储在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);
}
}
答案 0 :(得分:2)
Axon Framework旨在为您提供轻松的构建基块,以与DDD,CQRS和事件源一起使用。通过这种方式,开箱即用提供了许多管道,使您在那条路上的生活尽可能轻松。
要了解这是如何工作的,值得注意的是假设共享样本集中在所有三个范例上。在这种情况下,您可以将“事件”用作应用程序的“命令”和“查询”端之间的同步手段(通常以不同模型的形式)。
应用程序的Command端将通过处理命令并验证其自身状态来处理业务验证。结果,将发布一个事件。在典型的Axon应用程序中,这是在聚合的生命周期内发生的。为了不让框架用户要求直接连接EventStore
或EventBus
,并增加了确保事件以正确顺序存储的所有复杂性,Axon提供了AggregateLifecycle#apply(Object)
方法。
通过这种方式,框架将能够自动找到用于发布事件的EventBus
,该事件也将最终出现在EventStore
中。
旁注