Spring Event事件用法 Spring Boot Event事件发布和监听 Spring Event事件发布 Spring Event事件订阅
一、概述
在Spring中可以使用 Spring Event 事件机制,实现功能解耦合。 本文 主要讲解 Spring Event的用法 ,至于那些 介绍啊,观察者模式,实现原理 ,请自行查找资料解决。
主要讲解以下几个方面内容:
-
- 事件发布
- 事件订阅 【监听】
- Spring 内置的4个事件
二、代码实现
1、事件发布 --- 普通对象
发布普通对象,任意的Java对象,都是可以作为 Spring Event的事件发布,该代码案例将 ApplicationContext发布普通对象事件
1.1、普通的 Java Bean UserInfo
@Data
public class UserInfo {
private Integer id ;
private String name;
}
1.2 ApplicationContext 发布事件
@Autowired
private ApplicationContext applicationContext;
@PostMapping("/register2")
public UserInfo register(@RequestBody UserInfo userInfo){
log.info("register success , userInfo ={}", JSON.toJSONString(userInfo));
applicationContext.publishEvent(userInfo);
return userInfo;
}
2、事件发布 --- ApplicationEvent 子类
发布ApplicationEvent对象,需要继承ApplicationEvent类,该代码案例将实现 ApplicationEventPublisherAware 接口,发布事件。
2.1、继承 ApplicationEvent 的 UserEvent 类
public class UserEvent extends ApplicationEvent {
private String userName ;
public UserEvent(String userName) {
super(userName);
this.userName = userName;
}
public String getUserName() {
return userName;
}
}
2.2、创建 PublishService类,用于事件发布
@Component
public class PublishService implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher ;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
publisher = applicationEventPublisher;
}
public void pub(Object event){
publisher.publishEvent(event);
}
}
2.3、PublishService类发布事件
@Autowired
private PublishService publishService;
@PostMapping("/register")
public UserEvent register(@RequestBody Map map){
String userName = "小明default";
if(Objects.nonNull(map.get("userName"))){
userName = map.get("userName").toString();
}
log.info("register success , userName ={}",userName);
final UserEvent userEvent = new UserEvent(userName);
// applicationContext.publishEvent(userEvent);
publishService.pub(userEvent);
return userEvent;
}
3、事件监听 --- ApplicationListener 接口
实现ApplicationListener接口,可以实现Spring Event事件的监听,缺点是,只能监听 ApplicationEvent 的子类对象,不能监听普通对象。
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
3.1、创建GeneralEventListener类,实现事件的监听
@Slf4j
@Component
public class GeneralEventListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
log.warn("GeneralEventListener name = {}" ,event.getClass().getSimpleName());
if(event instanceof ContextRefreshedEvent){
log.info("ContextRefreshedEvent execute ~~ !");
}
if(event instanceof UserEvent){
System.out.println(Thread.currentThread().getName()+" , GeneralEventListener userName="+event.getSource());
}
}
}
4、事件监听 --- @EventListener 注解
@EventListener 注解,可以实现全部的Spring Event事件的监听,包括:ApplicationEvent和普通的Java对象,都可以进行监听。 @EventListener注解中,可以通过属性配置,实现指定的事件监听。
4.1、创建UserEventListener类,实现事件监听
@Slf4j
@Component
public class UserEventListener {
/**
* Description: 监听 普通对象 --- 非 ApplicationEvent 的子类
* @param userInfo
* @return void
* @version v1.0
* @author wu
* @date 2023/4/24 13:59
*/
@EventListener
public void onUserInfo(UserInfo userInfo){
log.info("onUserInfo~ value={}", JSON.toJSONString(userInfo));
msgService.sendMsg(userInfo.getName());
}
}
三、总结
1、本文总结了 Spring Event事件的用法和代码案例,可以发布普通对象和ApplicationEvent对象事件,同理可以监听 对应的两种事件。 日常开发中,建议使用 @EventListener 注解监听事件,功能更强大。
2、Spring 内置的4个事件分别是:
-
-
- ContextStartedEvent:Spring Context 启动完成事件。
- ContextStoppedEvent:Spring Context 停止完成事件。
- ContextClosedEvent:Spring Context 停止开始事件。
- ContextRefreshedEvent:Spring Context 初始化或刷新完成事件。
-
3、经过测试,Spring Event事件执行,默认是同步执行,即: 发布事件后,需要等待 事件监听方,代码执行完毕后,才会继续往下执行。若要调整为异步执行,可以使用@Async注解来实现异步,或者使用线程池来实现异步。
@Async // 事件异步执行
@EventListener
public void onUserInfo(UserInfo userInfo){
log.info("onUserInfo~ value={}", JSON.toJSONString(userInfo));
msgService.sendMsg(userInfo.getName());
}
参考资料:
Spring 异步@Async注解用法