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

public class Mains extends ApplicationEvent {
public Mains(Object name) {
super(name);
System.out.println(String.format("Hi,我是被監(jiān)聽(tīng)的%s!",name));
}
}
@Component
public class ListenerMains {
//@Async // 開(kāi)啟異步就無(wú)法使用@Order(0)進(jìn)行排序了
@Order(0)
@EventListener(Mains.class)
public void listener(Mains mains){
System.out.println("這是第一個(gè)監(jiān)聽(tīng)類 "+mains.getSource());
}
//@Async
@Order(1)
@EventListener(Mains.class)
public void listener2(Mains mains){
System.out.println("這是第二個(gè)監(jiān)聽(tīng)類 "+mains.getSource());
}
//@Async
@Order(2)
@EventListener(Mains.class)
public void listener3(Mains mains){
System.out.println("這是第三個(gè)監(jiān)聽(tīng)類 "+mains.getSource());
}
}
public class TestController {
@Autowired
GetAccessToken getAccessToken;
@Autowired
ApplicationEventPublisher publisher;
@RequestMapping("test")
public Object get() {
publisher.publishEvent(new Mains("哈哈哈哈"));
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Spring事件監(jiān)聽(tīng)器@EventListener與publishEvent的使用
- SpringBoot中的ApplicationListener事件監(jiān)聽(tīng)器使用詳解
- Spring事件監(jiān)聽(tīng)器ApplicationListener源碼詳解
- springboot?事件監(jiān)聽(tīng)器的案例詳解
- Spring事件監(jiān)聽(tīng)器之@EventListener原理分析
- SpringBoot加載應(yīng)用事件監(jiān)聽(tīng)器代碼實(shí)例
- Spring中的事件監(jiān)聽(tīng)器使用學(xué)習(xí)記錄
相關(guān)文章
java8新特性-Stream入門(mén)學(xué)習(xí)心得
這篇文章主要介紹了java8新特性-Stream入門(mén)學(xué)習(xí)心得,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
mybatis mapper.xml獲取insert后的自增ID問(wèn)題
這篇文章主要介紹了mybatis mapper.xml獲取insert后的自增ID問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Java語(yǔ)言中cas指令的無(wú)鎖編程實(shí)現(xiàn)實(shí)例
這篇文章主要介紹了Java語(yǔ)言中cas指令的無(wú)鎖編程實(shí)現(xiàn)實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-09-09
SpringBoot整合log4j2日志的實(shí)現(xiàn)
在項(xiàng)目推進(jìn)中,如果說(shuō)第一件事是搭Spring框架的話,那么第二件事情就是在Sring基礎(chǔ)上搭建日志框架,大家都知道日志對(duì)于一個(gè)項(xiàng)目的重要性,尤其是線上Web項(xiàng)目,因?yàn)槿罩究赡苁俏覀兞私鈶?yīng)用如何執(zhí)行的唯一方式。此篇文章是博主在實(shí)踐中用Springboot整合log4j2日志的總結(jié)2021-06-06
詳解Java如何實(shí)現(xiàn)數(shù)值校驗(yàn)的算法
給定一個(gè)字符串如何判斷它是否為數(shù)值類型?本文將帶著大家學(xué)習(xí)一下如何利用Java實(shí)現(xiàn)這個(gè)判斷算法,感興趣的小伙伴可以學(xué)習(xí)一下2022-04-04
解決spring-data-jpa 事物中修改屬性自動(dòng)更新update問(wèn)題
這篇文章主要介紹了解決spring-data-jpa 事物中修改屬性自動(dòng)更新update問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家2021-08-08

