這篇文章給大家分享的是有關(guān)SpringBoot如何發(fā)布ApplicationEventPublisher和監(jiān)聽(tīng)ApplicationEvent事件的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括新邱網(wǎng)站建設(shè)、新邱網(wǎng)站制作、新邱網(wǎng)頁(yè)制作以及新邱網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,新邱網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到新邱省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
實(shí)現(xiàn)方法
自定義需要發(fā)布的事件類(lèi),需要繼承ApplicationEvent類(lèi)或PayloadApplicationEvent
使用@EventListener來(lái)監(jiān)聽(tīng)事件
使用ApplicationEventPublisher來(lái)發(fā)布自定義事件(@Autowired注入即可)
/** * 自定義保存事件 * @author peter * 2019/1/27 14:59 */ public class PersonSaveEvent extends ApplicationEvent { private DATA data; public PersonSaveEvent(DATA source) { super(source); this.data = source; } public DATA getData() { return data; } } //發(fā)布事件 public void savePerson(Person person){ personDao.save(person); publisher.publishEvent(new PersonSaveEvent<>(1)); } //監(jiān)聽(tīng)事件 @EventListener public void listenEvent(PersonSaveEventevent) { System.out.println("監(jiān)聽(tīng)到PersonSaveEvent事件; 接收到的值:" + event.getData() + ";發(fā)布的時(shí)間為" + Instant.ofEpochMilli(event.getTimestamp())); }
好處
可以使核心業(yè)務(wù)與子業(yè)務(wù)進(jìn)行解耦,也方便后期的業(yè)務(wù)的擴(kuò)展。如新用戶注冊(cè)之后,需要發(fā)放優(yōu)惠券,此時(shí)可以在保存用戶之后,發(fā)布一個(gè)新用戶的注冊(cè)成功事件,通過(guò)監(jiān)聽(tīng)該事件來(lái)實(shí)現(xiàn)發(fā)放優(yōu)惠券的功能。后期新增一個(gè)對(duì)新用戶進(jìn)行xxx功能,此時(shí)可以新寫(xiě)一個(gè)監(jiān)聽(tīng)注冊(cè)成功事件的監(jiān)聽(tīng)器,來(lái)處理新的業(yè)務(wù)邏輯,而不需要修改之前的注冊(cè)邏輯。
注意事項(xiàng)
1、監(jiān)聽(tīng)器方法中一定要try-catch異常,否則會(huì)造成發(fā)布事件(有事物的)的方法進(jìn)行回滾
2、可以使用@Order注解來(lái)控制多個(gè)監(jiān)聽(tīng)器的執(zhí)行順序,@Order傳入的值越小,執(zhí)行順序越高
3、對(duì)于需要進(jìn)行事物監(jiān)聽(tīng)或不想try-catch runtime異常,可以使用@TransactionalEventListener注解
@TransactionalEventListener 監(jiān)聽(tīng)器
在該注解的源碼中:
*If the event is not published within the boundaries of a managed transaction, the * event is discarded unless the {@link #fallbackExecution} flag is explicitly set. If a * transaction is running, the event is processed according to its {@code TransactionPhase}.
大意是:如果事件的發(fā)布不是在事物(@Transactional)范圍內(nèi),則監(jiān)聽(tīng)不到該事件,除非將fallbackExecution標(biāo)志設(shè)置為true(@TransactionalEventListener(fallbackExecution = true));如果在事物中,可以選擇在事物的哪個(gè)階段來(lái)監(jiān)聽(tīng)事件,默認(rèn)在事物提交后監(jiān)聽(tīng)。
修改監(jiān)聽(tīng)事物的范圍:@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
在監(jiān)聽(tīng)器中重新開(kāi)一個(gè)事物
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION) public void listenEvent1(PersonSaveEventevent) { divide(event); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void divide(PersonSaveEvent event) { System.out.println("監(jiān)聽(tīng)到PersonSaveEvent事件; 接收到的值:" + event.getData() + ";接受的時(shí)間為" + Instant.ofEpochMilli(event.getTimestamp())); }
以上事件都是同步,如果需要異步則需要開(kāi)啟異步支持,在監(jiān)聽(tīng)器方法加上@Async 注解即可。
/** * @author peter * @version 1.0 * @date 2019/04/18 08:47 */ @Configuration @EnableAsync public class AsyncEventConfiguration implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { return Executors.newCachedThreadPool(); } }
一旦開(kāi)始異步執(zhí)行,方法的異常將不會(huì)拋出,只能在方法內(nèi)部處理。
感謝各位的閱讀!關(guān)于“SpringBoot如何發(fā)布ApplicationEventPublisher和監(jiān)聽(tīng)ApplicationEvent事件”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!