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
接口service
短信通知实体类
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请求接口
查看数据库是否成功保存数据
查看控制台日志事件监听是否被正确异步触发执行
可以看到业务接口已经执行完了,发送短信是异步执行的
至此,SpringBoot实现异步事件监听结束了。