Spring事件監(jiān)聽機制ApplicationEvent方式
前言
ApplicationEvent 以及 Listener 是Spring為我們提供的一個事件監(jiān)聽、訂閱的實現,內部實現原理是觀察者設計模式,設計初衷也是為了系統(tǒng)業(yè)務邏輯之間的解耦,提高可擴展性以及可維護性。
ApplicationEvent的小demo
ApplicationEvent本身是抽象類,無法直接實例化。一般通過子類繼承ApplicationEvent
public class MyApplicationEvent extends ApplicationEvent {
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public MyApplicationEvent(Object source) {
super(source);
}
public MyApplicationEvent(Object source, Student student) {
super(source);
this.student = student;
}
}事件定義好之后,我們注冊個事件監(jiān)聽器即可。
實現ApplicationListener接口注冊監(jiān)聽器
@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(MyApplicationListener.class);
@Override
public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
Student student = myApplicationEvent.getStudent();
LOGGER.info("學生對象是={}", JSONObject.toJSONString(student));
}
}通過@EventListener注冊監(jiān)聽器,ApplicationContext.publishEvent 默認是同步操作, 并非發(fā)布后不管的異步操作,發(fā)布事件后需要等 @EventListener 執(zhí)行完。
如果需要開啟異步操作 需要在 @EventListener 上 增加 @Async 注解。
@Component
public class AsyncApplicationListener {
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncApplicationListener.class);
@EventListener
@Async
public void listener(MyApplicationEvent myApplicationEvent) {
Student student = myApplicationEvent.getStudent();
LOGGER.info("通過@EventListener獲取學生對象信息={}", JSONObject.toJSONString(student));
}
}通過實現SmartApplicationListener接口注冊監(jiān)聽器
SmartApplicationListener接口繼承了全局監(jiān)聽ApplicationListener,并且泛型對象使用的ApplicationEvent來作為全局監(jiān)聽,可以理解為使用SmartApplicationListener作為監(jiān)聽父接口的實現,監(jiān)聽所有事件發(fā)布。
既然是監(jiān)聽所有的事件發(fā)布,那么SmartApplicationListener接口添加了兩個方法supportsEventType、supportsSourceType來作為區(qū)分是否是我們監(jiān)聽的事件,只有這兩個方法同時返回true時才會執(zhí)行onApplicationEvent方法。
@Component
public class MySmartApplicationListener implements SmartApplicationListener {
private static final Logger LOGGER = LoggerFactory.getLogger(MySmartApplicationListener.class);
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) {
return aClass == MyApplicationEvent.class;
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
return sourceType == ApplicationRunnerTest.class;
}
@Override
public int getOrder() {
return 0;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
MyApplicationEvent myApplicationEvent = (MyApplicationEvent) applicationEvent;
LOGGER.info("通過MySmartApplicationListener 獲取學生對象信息={}",
JSONObject.toJSONString(myApplicationEvent.getStudent()));
}
}可以看到除了上面的方法,還提供了一個getOrder方法,這個方法就可以解決執(zhí)行監(jiān)聽的順序問題,return的數值越小證明優(yōu)先級越高,執(zhí)行順序越靠前
發(fā)布事件
在Spring的Bean中,注入ApplicationContext ,通過ApplicationContext 來進行事件發(fā)布
@Autowired
private ApplicationContext applicationContext;
applicationContext.publishEvent(new MyApplicationEvent(this, new Student("愛琴孩", 18)));運行結果
2023-01-28 10:38:39.696 YYZX_Study 13540 [ main] INFO c.e.s.s.MySmartApplicationListener 37: 通過MySmartApplicationListener 獲取學生對象信息={"age":18,"name":"愛琴孩"}
2023-01-28 10:38:39.696 YYZX_Study 13540 [ main] INFO c.e.study.service.MyApplicationListener 22: 學生對象是={"age":18,"name":"愛琴孩"}
2023-01-28 10:38:39.696 YYZX_Study 13540 [tOrderService-1] INFO c.e.s.service.AsyncApplicationListener 25: 通過@EventListener獲取學生對象信息={"age":18,"name":"愛琴孩"}
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
解決Hibernate4執(zhí)行save()或update()無效問題的方法
這篇文章主要為大家詳細介紹了解決Hibernate4執(zhí)行save()或update()無效問題的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-06-06
Java基于ServletContextListener實現UDP監(jiān)聽
這篇文章主要介紹了Java基于ServletContextListener實現UDP監(jiān)聽,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-12-12
詳解SpringBoot中添加@ResponseBody注解會發(fā)生什么
這篇文章主要介紹了詳解SpringBoot中添加@ResponseBody注解會發(fā)生什么,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11

