Spring的事件和監(jiān)聽器-同步與異步詳解
Spring的事件和監(jiān)聽器-同步與異步
Application下抽象子類ApplicationContextEvent的下面有4個已經(jīng)實現(xiàn)好的事件
ContextClosedEvent
(容器關(guān)閉時)ContextRefreshedEvent
(容器刷新是)ContextStartedEvent
(容器啟動時候)ContextStoppedEvent
(容器停止的時候)
同樣,這四個事件都繼承了ApplicationEvent,如果我們想自定義事件,也可以通過繼承ApplicationEvent來實現(xiàn)
1、首先新建StartWorkflowEvent.java,
繼承ApplicationEvent抽象類
public class StartWorkflowEvent extends ApplicationEvent { //存放構(gòu)造器送入的值 private String msg; //構(gòu)造器參數(shù)可以隨意設置,這里為了方便調(diào)試,設置為字符串 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注解異步調(diào)用時使用, 異步調(diào)用時, 需要在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、相關(guān)的配置
<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ù)已經(jīng)被占用滿后,新的任務會被放進queue里面,當這個 queue的capacity也被占滿之后,pool里面會創(chuàng)建新線程處理這個任務,直到總線程數(shù)達到了max size,這時系統(tǒng)會拒絕這個任務并拋出TaskRejectedException異常(缺省配置的情況下,可以通過rejection-policy 來決定如何處理這種情況)。缺省值為:Integer.MAX_VALUEkeep-alive
:超過core size的那些線程,任務完成后,再經(jīng)過這個時長(秒)會被結(jié)束掉rejection-policy
:當pool已經(jīng)達到max size的時候,如何處理新任務ABORT
(缺?。簰伋鯰askRejectedException異常,然后不執(zhí)行DISCARD
:不執(zhí)行,也不拋出異常DISCARD_OLDEST
:丟棄queue中最舊的那個任務CALLER_RUNS
:不在新線程中執(zhí)行任務,而是有調(diào)用者所在的線程來執(zhí)行
Spring事件、異步監(jiān)聽
使用事件的模式可以對系統(tǒng)進行解耦,事件源發(fā)布一個事件,
事件監(jiān)聽器可以消費這個事件,而事件源不用關(guā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("哈哈哈哈")); } }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis mapper.xml獲取insert后的自增ID問題
這篇文章主要介紹了mybatis mapper.xml獲取insert后的自增ID問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05解決spring-data-jpa 事物中修改屬性自動更新update問題
這篇文章主要介紹了解決spring-data-jpa 事物中修改屬性自動更新update問題,具有很好的參考價值,希望對大家2021-08-08