我正在尝试使用Spring Boot/Spring Data实现一个应用程序,遵循DDD体系结构指南。我有一个聚合根,它使用方法AbstractAggregateRoot::registerEvent((发布域事件。此外,出于日志记录/跟踪的目的,我需要拦截这些事件,所以我决定做一个实验:
首先,实现一个自定义ApplicationEvent Publisher
public class CustomEventPublisher implements ApplicationEventPublisher {
private final ApplicationEventPublisher publisher;
private final Logger logger = getLogger(CustomEventPublisher.class);
public CustomEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
@Override
public void publishEvent(ApplicationEvent event) {
logger.info("sending an event...");
publisher.publishEvent(event);
}
//.....
}
然后注册为bean
@Configuration
public class CustomEventPublisherConfig {
@Bean
@Primary
public ApplicationEventPublisher getCustomEventPublisher(ApplicationEventPublisher publisher , RabbitTemplate rabbitTemplate) {
return new CustomEventPublisher(publisher, rabbitTemplate);
}
}
一旦我使用注入的ApplicationEventPublisher 从某个示例对象显式发布事件,这就可以正常工作
public void pub() {
publisher.publishEvent(new Event(this , 1));
}
@EventListener
public void sub(Event e) {
this.value = e.getValue();
}
并且我得到了"正在发送事件">日志条目
然后我尝试定义聚合根
@Entity
public class AggregateRoot extends AbstractAggregateRoot {
@Id
@GeneratedValue
private Long id;
private int value = 0;
public AggregateRoot setValue(int value) {
registerEvent(new Event(this , value));
return this;
}
}
和
public void pub() {
repository.save(new AggregateRoot().setValue(1));
}
测试再次通过,但我可以清楚地看到Spring Data没有使用CustomEventPublisher。我试图了解是否有某种方法可以拦截repository.save((调用并覆盖默认行为,即使需要重新发明轮子,这种方法也可以工作(尽管我不认为域事件发布代码如此复杂(,但我发现的唯一一件事是关于Spring Data REST的,它超出了我的范围
有什么建议可以克服这个问题吗?
提前感谢
据我所知,Spring没有提供替换EventPublishingRepositoryProxyPostProcessor
使用的发布服务器的方法。在我看来,你选择了一条不太正确的道路来实现你想要实现的目标,所以我不是在回答你的直接问题,而是在回答你一开始描述的要求。
我建议您使用@EventListener
注册一个监听器,并在那里处理您的事件:
@EventListener
public void handleEvent(Event event) {
System.out.println(event);
}
或者,您可以使用@TransactionalEventListener
将侦听器绑定到事务阶段:
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
public void handleEvent(Event event) {
System.out.println(event);
}