不使用消息中间件,也可以完成事件通知

343 阅读2分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战

前言

在平时的业务场景中,我们总会遇到需要在主业务流程完成后,做一些通知,如:注册成功的邮件通知、支付成功的系统通知,这时候一般都是几种技术方案

  1. 消息中间件(异步)
  2. 使用spring事件监听(同步+异步) 如果是一些规模比较新的公司或者新的项目,不需要一下子就继承中间件,使用spring事件监听也是一个很好的办法。

spring事件监听

使用步骤

  1. 定义事件发布器,需要实现ApplicationEventPublisherAware接口
  2. 定义事件监听器,需要继承ApplicationEvent类
  3. 定义响应事件,需要继承ApplicationListener接口

定义事件发布器,ApplicationEventPublisherAware

@Component
public class EventDistributor implements ApplicationEventPublisherAware {

    private static ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        EventDistributor.applicationEventPublisher = applicationEventPublisher;
    }

  /**
     * 发布同步事件
     * @param event 事件主题
     */
    public static void publishEvent(ApplicationEvent event) {
        try {
            applicationEventPublisher.publishEvent(event);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("事件发布成功,有部分执行失败");
        }
    }

    /**
     * 发布异步事件,会等待当前事务提交完成后再进行事件发布
     * @param event 事件主题
     */
    public static void publishTransactionSyncEvent(ApplicationEvent event) {
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
              try{
                  applicationEventPublisher.publishEvent(event);
              }catch (Exception e){
                  e.printStackTrace();
              }
            }
        });
    }
}

TransactionSynchronizationManager

事务同步管理器。只有等事务提交成功之后,才会只是实现的具体逻辑 TransactionSynchronizationAdapter是一个适配器:它实现了TransactionSynchronization接口,并为每一个接口方法提供了一个空的实现。这类适配器的基本思想是:接口中定义了很多方法,然而业务代码往往只需要实现其中一小部分。利用这种“空实现”适配器,我们可以专注于业务上需要处理的回调方法,而不用在业务类中放大量而且重复的空方法。

定义事件监听器,ApplicationEvent

public class TicketAddEvent extends ApplicationEvent {
    public TicketAddEvent(ClienteleTicketMessage userTicketMessage) {
        super(userTicketMessage);
    }

}

在需要被监听处使用:

EventDistributor.publishEvent(new TicketAddEvent(参数)); 

定义响应事件,ApplicationListener

@Component
public class TicketOverviewListener implements ApplicationListener<TicketAddEvent> {
    @Async//异步
    @Override
    public void onApplicationEvent(TicketAddEvent ticketAddEvent) {
        ClienteleTicketMessage userTicketMessage = (ClienteleTicketMessage) ticketAddEvent.getSource();//接受参数
        //业务响应逻辑
}

到此监听就完成

后言

当我们不想为了一个监听引入一个中间件时或想事务结束在执行监听,Spring提供了很好的接口来给我们扩展,希望本篇文章对你有一定的帮助,我是一名不想秃头的还未秃头的新生代农民,我们下次再见。