Spring的事件和監(jiān)聽器-同步與異步詳解
Spring的事件和監(jiān)聽器-同步與異步
Application下抽象子類ApplicationContextEvent的下面有4個已經實現(xiàn)好的事件
ContextClosedEvent(容器關閉時)ContextRefreshedEvent(容器刷新是)ContextStartedEvent(容器啟動時候)ContextStoppedEvent(容器停止的時候)
同樣,這四個事件都繼承了ApplicationEvent,如果我們想自定義事件,也可以通過繼承ApplicationEvent來實現(xiàn)
1、首先新建StartWorkflowEvent.java,
繼承ApplicationEvent抽象類
public class StartWorkflowEvent extends ApplicationEvent {
//存放構造器送入的值
private String msg;
//構造器參數(shù)可以隨意設置,這里為了方便調試,設置為字符串
public StartWorkflowEvent (String msg) {
super(msg);
this.msg=msg;
}
//自定義一個方法,這個方法也可以隨意寫,這里也是測試用
public void myevent(){
System.out.println("********My event**************");
System.out.println(msg);
System.out.println("*******************************");
}
}
2、新建一個監(jiān)聽器StartWorkflowListener.java
實現(xiàn)ApplicationListener<StartWorkflowEvent>
/**
* 發(fā)起流程事件監(jiān)聽
*/
@Component("startWorkflowListener")
public class StartWorkflowListener implements ApplicationListener<StartWorkflowEvent> {
@Autowired
private OaWorkflowHepler oaWorkflowHepler;
//@Async注解異步調用時使用, 異步調用時, 需要在xml配置文件中添加 <task:annotation-driven />
// @Async
@Override
public void onApplicationEvent(StartWorkflowEvent event) {
oaWorkflowHepler.start(event.getMsg());
}
}
3、創(chuàng)建一個事件發(fā)布類EventPublisher.java
/**
* 發(fā)布事件
*/
@Component("eventPublisher")
public class EventPublisher {
@Autowired
private ApplicationContext applicationContext;
/**
* 發(fā)布事件
* @param event
*/
public void publishEvent(ApplicationEvent event) {
applicationContext.publishEvent(event);
}
}
4、相關的配置
<task:annotation-driven />配置:
executor:指定一個缺省的executor給@Async使用。
例子:
<task:annotation-driven executor="asyncExecutor" />
<task:executor />配置參數(shù):
id:當配置多個executor時,被@Async("id")指定使用;也被作為線程名的前綴。core size:最小的線程數(shù),缺?。?max size:最大的線程數(shù),缺?。篒nteger.MAX_VALUEqueue-capacity:當最小的線程數(shù)已經被占用滿后,新的任務會被放進queue里面,當這個 queue的capacity也被占滿之后,pool里面會創(chuàng)建新線程處理這個任務,直到總線程數(shù)達到了max size,這時系統(tǒng)會拒絕這個任務并拋出TaskRejectedException異常(缺省配置的情況下,可以通過rejection-policy 來決定如何處理這種情況)。缺省值為:Integer.MAX_VALUEkeep-alive:超過core size的那些線程,任務完成后,再經過這個時長(秒)會被結束掉rejection-policy:當pool已經達到max size的時候,如何處理新任務ABORT(缺?。簰伋鯰askRejectedException異常,然后不執(zhí)行DISCARD:不執(zhí)行,也不拋出異常DISCARD_OLDEST:丟棄queue中最舊的那個任務CALLER_RUNS:不在新線程中執(zhí)行任務,而是有調用者所在的線程來執(zhí)行
Spring事件、異步監(jiān)聽
使用事件的模式可以對系統(tǒng)進行解耦,事件源發(fā)布一個事件,
事件監(jiān)聽器可以消費這個事件,而事件源不用關注發(fā)布的事件有哪些監(jiān)聽器,
這可以對系統(tǒng)進行解耦

public class Mains extends ApplicationEvent {
public Mains(Object name) {
super(name);
System.out.println(String.format("Hi,我是被監(jiān)聽的%s!",name));
}
}
@Component
public class ListenerMains {
//@Async // 開啟異步就無法使用@Order(0)進行排序了
@Order(0)
@EventListener(Mains.class)
public void listener(Mains mains){
System.out.println("這是第一個監(jiān)聽類 "+mains.getSource());
}
//@Async
@Order(1)
@EventListener(Mains.class)
public void listener2(Mains mains){
System.out.println("這是第二個監(jiān)聽類 "+mains.getSource());
}
//@Async
@Order(2)
@EventListener(Mains.class)
public void listener3(Mains mains){
System.out.println("這是第三個監(jiān)聽類 "+mains.getSource());
}
}
public class TestController {
@Autowired
GetAccessToken getAccessToken;
@Autowired
ApplicationEventPublisher publisher;
@RequestMapping("test")
public Object get() {
publisher.publishEvent(new Mains("哈哈哈哈"));
}
}
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringBoot整合Prometheus如何實現(xiàn)資源監(jiān)控
本文介紹了如何使用Prometheus監(jiān)控SpringBoot應用,Prometheus是一個開源的監(jiān)控和告警工具,SpringBootActuator提供了監(jiān)控和管理SpringBoot應用的工具,通過添加依賴、配置Actuator和Prometheus,可以實現(xiàn)對SpringBoot應用的實時監(jiān)控2024-12-12
MyBatis 添加元數(shù)據自定義元素標簽的實現(xiàn)代碼
這篇文章主要介紹了MyBatis 添加元數(shù)據自定義元素標簽的實現(xiàn)代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
Spring?Boot應用程序中如何使用Keycloak詳解
這篇文章主要為大家介紹了Spring?Boot應用程序中如何使用Keycloak詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05
詳談Enumeration接口和Iterator接口的區(qū)別
下面小編就為大家?guī)硪黄斦凟numeration接口和Iterator接口的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
java Servlet 實現(xiàn)動態(tài)驗證碼圖片示例
這篇文章主要介紹了java Servlet 實現(xiàn)動態(tài)驗證碼圖片示例的資料,這里整理了詳細的代碼,有需要的小伙伴可以參考下。2017-02-02

