@EventListener事件监听
使用场景举例
用户注册后执行 -> 1.发送注册成功邮件、2.发送优惠券。不管后面的1、2执行是否成功,都应保证用户注册功能不受影响。
使用方式
- 创建事件类。其实就是定义一个实体类,里面是业务处理用到的参数
java
/*
* 自定义的一个实体类,Spring会默认将其包装在PayloadApplicationEvent中
* 当使用@EventListener时,需指定指定参数value或class,防止多个事件冲突
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRegisterEvent {
//用户名
private String userName;
}
- 创建监听类。监听事件进行后续处理,注意使用时需要指定classes事件类,防止冲突
java
**
* 多个监听器一定指定事件类型,防止发生冲突
* 如:@EventListener(classes = UserRegisterEvent.class)
*/
@Component
public class UserRegisterListener {
/*
* 只监听UserRegisterEvent事件
* 使用Order来表示同一事件的执行顺序,数值越小优先级越高
*/
@Order(2)
@EventListener(classes = UserRegisterEvent.class)
public void sendMail(UserRegisterEvent event) {
System.out.println(Thread.currentThread().getName() + " ---> " + String.format("给用户【%s】发送注册成功邮件!", event.getUserName()));
}
@Order(1)
@EventListener(classes = UserRegisterEvent.class)
public void sendCompon(UserRegisterEvent event) {
System.out.println(Thread.currentThread().getName() + " ---> " + String.format("给用户【%s】发送优惠券!", event.getUserName()));
}
/*
* 只监听GoodsPriceEvent事件
* 也就是当触发上面的UserRegisterEvent事件时,不会执行,避免了冲突
*/
@EventListener(classes = GoodsPriceEvent.class)
@Order(4)
public void sendMail2(Object event) {
System.out.println(Thread.currentThread().getName() + " ---> " + "我也执行了222222222!");
}
}
错误的使用
指定事件类时,不要写Object.class
,因为它不是一个明确的事件类,它能监听到所有事件
java
**
* 多个监听器一定指定事件类型,防止发生冲突
* 如:@EventListener(classes = UserRegisterEvent.class)
*/
@Component
public class UserRegisterListener {
/*
* Object类型不要写,所有的事件他都会执行
*/
@EventListener(classes = Object.class)
@Order(3)
public void sendMail1(Object event) {
System.out.println(Thread.currentThread().getName() + " ---> " + "我也执行了111111111!");
}
}
事件广播
java
/*
* 这里就是你的Service业务处理类
* 使用ApplicationEventPublisher发送
* 当然也可以使用ApplicationContext发送,因为ApplicationContext继承了ApplicationEventPublisher,使用哪个都行
*/
@Service
public class UserRegisterService {
/*
* 和ApplicationContext任选其一即可
*/
@Resource
private ApplicationEventPublisher applicationEventPublisher;
/*
* 和ApplicationEventPublisher任选其一即可
*/
@Resource
private ApplicationContext applicationContext;
/**
* 负责用户注册及发布事件的功能
*
* @param userName 用户名
*/
public void registerUser(String userName) {
//用户注册(将用户信息入库等操作)
System.out.println(String.format("用户【%s】注册成功", userName));
//发布注册成功事件
applicationEventPublisher.publishEvent(new UserRegisterEvent(userName));
}
}