Spring?@EventListener?異步中使用condition的問(wèn)題及處理
@EventListener 異步中使用condition的問(wèn)題
@EventListener是spring在4.2+推出的更好的使用spring事件架構(gòu)的方式,并且異步方式也很好設(shè)定
但是在spring4.2.7版本上使用eventlistener的condition 的使用需要注意以下情況可能失效:
condition 使用例子如
@EventListener(condition = "#event.isAsync")
1. 需要對(duì)同一個(gè)事件進(jìn)行區(qū)分同步異步
2. 使用condition來(lái)進(jìn)行過(guò)濾
例如:
需要對(duì)事件用condition進(jìn)行區(qū)分同步異步
@Async
@EventListener(condition = "#event.isAsync")
public void handleOrderCreatedEventAsync(TestEvent event) {
}
@EventListener(condition = "#event.isAsync == false")
public void handleOrderCreatedEvent(TestEvent event) {
}
修正的做法,是使用兩個(gè)事件區(qū)分即
@Async
@EventListener
public void handleOrderCreatedEventAsync(TestEventAsync event) {
}
@EventListener
public void handleOrderCreatedEvent(TestEvent event) {
}
還不清楚,在更高的版本上是否已經(jīng)有進(jìn)一步的修正,待以后研究
Spring事件的condition使用說(shuō)明
在開(kāi)發(fā)中使用了spring的事件機(jī)制,但是發(fā)現(xiàn)了一個(gè)問(wèn)題:如果多個(gè)發(fā)布的事件對(duì)象是同一個(gè)類型,而除了使用了這個(gè)事件類型作為參數(shù)的事件處理方法還是多個(gè),那就無(wú)法區(qū)分到底要執(zhí)行哪個(gè)處理方法了,除非你想每個(gè)處理方法都執(zhí)行。
如下是我的事件處理代碼聲明
@Async @EventListener public void handleExport(ExportExcelMessage<DTO> exportMsg){ }
這里的業(yè)務(wù)場(chǎng)景是異步導(dǎo)出Excel。直接用@EventListener來(lái)聲明事件處理方法。
在controller中我如此調(diào)用
publisher.publish(new ExportExcelMessage<>(reqDTO));
ExportExcelMessage是個(gè)事件對(duì)象,包含事件基本屬性,reqDTO就是查詢條件數(shù)據(jù)了。
開(kāi)始感覺(jué)沒(méi)有問(wèn)題。后來(lái)突然有一個(gè)相同類型入?yún)ⅲ╮eqDTO)的導(dǎo)出功能。
這樣處理方法就有問(wèn)題了。出現(xiàn)處理方法的重復(fù)執(zhí)行。
隨便上網(wǎng)一查,簡(jiǎn)單,EventListener直接加condition屬性就搞定。網(wǎng)上是這樣的;
@EventListener(condition="#exportMsg.source=='xxx'")
其中這個(gè)source就是ExportExcelMessage類的的一個(gè)屬性,用來(lái)區(qū)分到底是誰(shuí)發(fā)起的事件。
使用SPel表達(dá)式,直接引用的方法的參數(shù)名,單我試驗(yàn)是不行的,異常顯示exportMsg應(yīng)該是個(gè)null。
估計(jì)應(yīng)該能在方法參數(shù)上加注解來(lái)處理吧,就像Contrller的@WebParam一樣,但我一時(shí)也沒(méi)找到。
最后,直接看人家的代碼注釋,。。。。自己笨的可以了。
如下就解決了
@EventListener(condition = "#root.args[0].source == 'xxx'")
root.args就是參數(shù)的數(shù)組,直接用下標(biāo)取就好了。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳功能詳解
在處理大文件傳輸或網(wǎng)絡(luò)不穩(wěn)定的情況下,文件斷點(diǎn)續(xù)傳功能顯得尤為重要,本文將詳細(xì)介紹如何使用Spring Boot實(shí)現(xiàn)文件的斷點(diǎn)續(xù)傳功能,需要的可以了解下2025-04-04
Spring Boot與RabbitMQ結(jié)合實(shí)現(xiàn)延遲隊(duì)列的示例
本篇文章主要介紹了Spring Boot與RabbitMQ結(jié)合實(shí)現(xiàn)延遲隊(duì)列的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
SpringBoot異步實(shí)現(xiàn) 的8種方式
在同步操作中,執(zhí)行到?發(fā)送短信?的時(shí)候,我們必須等待這個(gè)方法徹底執(zhí)行完才能執(zhí)行?贈(zèng)送積分?這個(gè)操作,如果?贈(zèng)送積分?這個(gè)動(dòng)作執(zhí)行時(shí)間較長(zhǎng),發(fā)送短信需要等待,這就是典型的同步場(chǎng)景,這篇文章主要介紹了SpringBoot異步實(shí)現(xiàn) 的8種方式,需要的朋友可以參考下2023-11-11
Spring Boot 實(shí)現(xiàn)Restful webservice服務(wù)端示例代碼
這篇文章主要介紹了Spring Boot 實(shí)現(xiàn)Restful webservice服務(wù)端示例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11
SpringBoot 多線程事務(wù)回滾的實(shí)現(xiàn)
本文是基于springboot的@Async注解開(kāi)啟多線程,并通過(guò)自定義注解和AOP實(shí)現(xiàn)的多線程事務(wù),避免繁瑣的手動(dòng)提交/回滾事務(wù),感興趣的可以了解一下2024-02-02
Spring boot動(dòng)態(tài)修改日志級(jí)別的方法
我們經(jīng)常會(huì)遇到業(yè)務(wù)想看debug日志的問(wèn)題,但是debug日志頻繁打印會(huì)對(duì)日志查看有影響,且日志多對(duì)系統(tǒng)也會(huì)有一定的壓力,因此,如果可以在需要的時(shí)候動(dòng)態(tài)臨時(shí)調(diào)整下日志的級(jí)別則是比較完美的,spring boot已經(jīng)支持這種功能,需要的朋友可以參考下2022-12-12
RocketMQ?ConsumeQueue與IndexFile實(shí)時(shí)更新機(jī)制源碼解析
這篇文章主要為大家介紹了RocketMQ?ConsumeQueue與IndexFile實(shí)時(shí)更新機(jī)制源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05

