詳解SpringBoot 發(fā)布ApplicationEventPublisher和監(jiān)聽ApplicationEvent事件
資料地址
實現(xiàn)方法
- 自定義需要發(fā)布的事件類,需要繼承ApplicationEvent類或PayloadApplicationEvent<T>(該類也僅僅是對ApplicationEvent的一層封裝)
- 使用@EventListener來監(jiān)聽事件
- 使用ApplicationEventPublisher來發(fā)布自定義事件(@Autowired注入即可)
/** * 自定義保存事件 * @author peter * 2019/1/27 14:59 */ public class PersonSaveEvent<DATA> 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)聽事件 @EventListener public void listenEvent(PersonSaveEvent<Integer> event) { System.out.println("監(jiān)聽到PersonSaveEvent事件; 接收到的值:" + event.getData() + ";發(fā)布的時間為" + Instant.ofEpochMilli(event.getTimestamp())); }
好處
可以使核心業(yè)務與子業(yè)務進行解耦,也方便后期的業(yè)務的擴展。如新用戶注冊之后,需要發(fā)放優(yōu)惠券,此時可以在保存用戶之后,發(fā)布一個新用戶的注冊成功事件,通過監(jiān)聽該事件來實現(xiàn)發(fā)放優(yōu)惠券的功能。后期新增一個對新用戶進行xxx功能,此時可以新寫一個監(jiān)聽注冊成功事件的監(jiān)聽器,來處理新的業(yè)務邏輯,而不需要修改之前的注冊邏輯。
注意事項
1、監(jiān)聽器方法中一定要try-catch異常,否則會造成發(fā)布事件(有事物的)的方法進行回滾
2、可以使用@Order注解來控制多個監(jiān)聽器的執(zhí)行順序,@Order傳入的值越小,執(zhí)行順序越高
3、對于需要進行事物監(jiān)聽或不想try-catch runtime異常,可以使用@TransactionalEventListener注解
@TransactionalEventListener 監(jiān)聽器
在該注解的源碼中:
* <p>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)聽不到該事件,除非將fallbackExecution標志設置為true(@TransactionalEventListener(fallbackExecution = true));如果在事物中,可以選擇在事物的哪個階段來監(jiān)聽事件,默認在事物提交后監(jiān)聽。
修改監(jiān)聽事物的范圍:@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
在監(jiān)聽器中重新開一個事物
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION) public void listenEvent1(PersonSaveEvent<Integer> event) { divide(event); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void divide(PersonSaveEvent<Integer> event) { System.out.println("監(jiān)聽到PersonSaveEvent事件; 接收到的值:" + event.getData() + ";接受的時間為" + Instant.ofEpochMilli(event.getTimestamp())); }
以上事件都是同步,如果需要異步則需要開啟異步支持,在監(jiān)聽器方法加上@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(); } }
一旦開始異步執(zhí)行,方法的異常將不會拋出,只能在方法內(nèi)部處理。如需在方法外處理異常:Async 異常處理在文章最后
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Java 8中Collectors.toMap空指針異常源碼解析
這篇文章主要為大家介紹了Java 8中Collectors.toMap空指針異常源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08SpringBoot實現(xiàn)點餐系統(tǒng)的登錄與退出功能流程詳解
結束了Springboot+MyBatisPlus也是開始了項目之旅,將從后端的角度出發(fā)來整理這個項目中重點業(yè)務功能的梳理與實現(xiàn)2022-10-10SpringBoot的@RestControllerAdvice作用詳解
這篇文章主要介紹了SpringBoot的@RestControllerAdvice作用詳解,@RestContrllerAdvice是一種組合注解,由@ControllerAdvice,@ResponseBody組成,本質(zhì)上就是@Component,需要的朋友可以參考下2024-01-01SpringBoot+Eureka實現(xiàn)微服務負載均衡的示例代碼
這篇文章主要介紹了SpringBoot+Eureka實現(xiàn)微服務負載均衡的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11Spring Boot靜態(tài)資源路徑的配置與修改詳解
最近在做SpringBoot項目的時候遇到了“白頁”問題,通過查資料對SpringBoot訪問靜態(tài)資源做了總結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-09-09java 實現(xiàn)計數(shù)排序和桶排序實例代碼
這篇文章主要介紹了java 實現(xiàn)計數(shù)排序和桶排序實例代碼的相關資料,需要的朋友可以參考下2017-02-02