SpringBoot实现异步事件监听

210 阅读2分钟

1、原理

Spring的事件(Application Event)为Bean与Bean之间的消息通信提供了支持;事件监听机制是一套很有用的机制,其原理就是观察者模式。

事件机制中有三种角色:发布事件者、事件、事件监听者

发布事件者:发布事件的对象

事件:事件的具体内容

事件监听者:等待处理事件的对象

2、应用场景

1、用户注册成功了,给用户发个短信通知

2、用户下单成功一直没付款,给用户发个短信通知

等等

3、好处

1、业务与业务之间解耦,符合依赖倒置原则 1、代码复用,更容易维护,也提高了执行效率

4、实现

启动类增加注解@EnableAsync

package com.example.springbootdemo;

import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

/**
 * 启动类
 * @author yurenwei
 */
@Slf4j
@EnableAsync
@MapperScan("com.example.springbootdemo.mapper")
@SpringBootApplication
public class SpringbootDemoApplication {

    public static void main(String[] args) {
        log.info("demo项目启动成功");
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }

}

controller

image.png

接口service

image.png

短信通知实体类

package com.example.springbootdemo.dto;

import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * <p>
 *  短信实体类
 * </p>
 *
 * @author yurenwei
 * @since 2023/9/14
 */
@Data
@Accessors(chain = true)
public class SmsDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 用户姓名
     */
    private String userName;

    /**
     * 手机号
     */
    private String phone;

    /**
     * 消息
     */
    private String msg;

}

短信通知事件event

package com.example.springbootdemo.event;

import com.example.springbootdemo.dto.SmsDTO;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;

/**
 * <p>
 *
 * </p>
 *
 * @author yurenwei
 * @since 2023/9/14
 */
@Getter
@Setter
public class SmsEvent extends ApplicationEvent {

    /**
     * 事件名称
     */
    private String eventName;

    /**
     * 短信参数
     */
    private SmsDTO sms;

    public SmsEvent(Object source,String eventName,SmsDTO sms){
        super(source);
        this.eventName=eventName;
        this.sms=sms;
    }

}

短信通知事件监听listener

package com.example.springbootdemo.event;

import com.example.springbootdemo.dto.SmsDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  短信事件监听
 * </p>
 *
 * @author yurenwei
 * @since 2023/9/14
 */
@Slf4j
@Component
public class SmsListener implements ApplicationListener<SmsEvent> {

    @Async
    @Override
    public void onApplicationEvent(SmsEvent smsEvent) {
        log.info("执行短信发送事件监听开始");
        log.info("监听到事件名称:{}",smsEvent.getEventName());

        SmsDTO sms = smsEvent.getSms();
        log.info("监听到发送短信参数:姓名:{},手机号:{},消息:{}",sms.getUserName(),sms.getPhone(),sms.getMsg());
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("执行短信发送事件监听结束");
    }
}

5、测试

通过apifox请求接口

image.png

查看数据库是否成功保存数据

image.png

查看控制台日志事件监听是否被正确异步触发执行

image.png 可以看到业务接口已经执行完了,发送短信是异步执行的

至此,SpringBoot实现异步事件监听结束了。