Java 使用自定义ApplicationEventPublisher发送Spring域事件

Java 使用自定义ApplicationEventPublisher发送Spring域事件,java,spring,spring-data-jpa,event-driven-design,domain-events,Java,Spring,Spring Data Jpa,Event Driven Design,Domain Events,我正试图按照DDD体系结构指南,使用Spring引导/Spring数据实现一个应用程序。我有一个聚合根,它使用AbstractAggregateRoot::registerEvent()方法发布域事件。此外,出于记录/跟踪的目的,我需要截获这些事件,因此我决定做一个实验: 首先,实现自定义ApplicationEvent发布服务器 public class CustomEventPublisher implements ApplicationEventPublisher { privat

我正试图按照DDD体系结构指南,使用Spring引导/Spring数据实现一个应用程序。我有一个聚合根,它使用AbstractAggregateRoot::registerEvent()方法发布域事件。此外,出于记录/跟踪的目的,我需要截获这些事件,因此我决定做一个实验:

首先,实现自定义ApplicationEvent发布服务器

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 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);
    }

    //.....
}
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;
    }
}

再次通过测试,但我可以清楚地看到Spring数据没有使用CustomEventPublisher。我试图了解是否有某种方法可以拦截repository.save()调用并覆盖默认行为,即使需要重新发明轮子(我不认为域事件发布代码如此复杂),这种方法也可以工作,但我发现的唯一一件事是Spring Data REST,它超出了我的范围

有没有克服这个问题的建议


提前感谢

据我所知,Spring并没有提供一种方法来取代所使用的发布服务器。在我看来,你们并没有选择一条正确的道路来实现你们的目标,所以我不是在回答你们的直接问题,而是在开始时描述了你们的要求

我建议您注册一个侦听器,并在那里处理您的事件:

@EventListener
public void handleEvent(Event event) {
    System.out.println(event);
}
或者,您可以使用将侦听器绑定到事务阶段:

@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
public void handleEvent(Event event) {
    System.out.println(event);
}

你能解释一下registerEvent(新事件(这个,值))吗在
AggregateRoot
@GSSwain好的,这是我到目前为止发现的。此外,TransactionalEventListener不是实验所必需的