使用Spring事件機制實現(xiàn)異步的方法
當把一個事件發(fā)布到Spring提供的ApplicationContext中,被監(jiān)聽器偵測到,就會執(zhí)行對應的處理方法。
事件本身
事件是一個自定義的類,需要繼承Spring提供的ApplicationEvent
。
@Data public class MyEvent extends ApplicationEvent { private String msg; public MyEvent(Object source, String msg) { super(source); this.msg = msg; } }
事件監(jiān)聽
基本方法是實現(xiàn)ApplicationListener
接口,自定義一個監(jiān)聽器,實現(xiàn)onApplicationEvent()
方法,然后添加到ApplicationContext
。
比如:
public class MyListener implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent event) { System.out.print("監(jiān)聽到MyEvent事件"); } } ... // SpringBoot的啟動類中添加監(jiān)聽器 public static void main(String[] args) { SpringApplication application = new SpringApplication(MyApplication.class); application.addListeners(new MyListener()); application.run(args); }
也可以使用注解@EventListener
(推薦):原理就是通過掃描這個注解,創(chuàng)建監(jiān)聽器并添加到ApplicationContext
。
@Component @Slf4j public class MyEventHandler { @EventListener public void handleEvent(MyEvent event) { log.info("------------處理事件:{}", event.getMsg()); try { Thread.sleep(5 * 1000L); log.info("事件1(5s)處理完成"); } catch (InterruptedException e) { e.printStackTrace(); } } }
事件發(fā)布
可以通過上下文對象的發(fā)布方法ConfigurableApplicationContext::publishEvent()
來發(fā)布。
也可以實現(xiàn)ApplicationEventPublisherAware
接口來發(fā)布(推薦)。
@Component @Slf4j public class EventService implements ApplicationEventPublisherAware { public ApplicationEventPublisher publisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } public String doEventWork(String msg) { log.info("------------publish event:" + msg); MyEvent event = new MyEvent(this, msg); publisher.publishEvent(event); return "OK"; } }
測試代碼
@SpringBootTest @RunWith(SpringRunner.class) public class EventServiceTest { @Autowired private EventService service; @Test public void eventTest() { String msg="Java Code"; service.doEventWork(msg); } }
注意
如果2個事件之間是繼承關系,會先監(jiān)聽到子類事件,處理完再監(jiān)聽父類。
// MyEvent2 extends MyEvent @Component @Slf4j public class MyEventHandler { @EventListener public void handleEvent(MyEvent event) { log.info("------------處理事件:{}", event.getMsg()); try { Thread.sleep(5 * 1000L); log.info("事件1(5s)處理完成"); } catch (InterruptedException e) { e.printStackTrace(); } } @EventListener public void handleEvent2(MyEvent2 event) { log.info("------------處理事件2:{}", event.getMsg()); try { Thread.sleep(10 * 1000L); log.info("事件2(10s)處理完成"); } catch (InterruptedException e) { e.printStackTrace(); } } }
當我publish一個子類事件MyEvent2時,日志如下:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
SpringBoot整合RabbitMQ及生產全場景高級特性實戰(zhàn)
本文主要介紹了SpringBoot整合RabbitMQ及生產全場景高級特性實戰(zhàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10SpringBoot實現(xiàn)識別圖片中的身份證號與營業(yè)執(zhí)照信息
這篇文章主要為大家詳細介紹了SpringBoot如何實現(xiàn)識別圖片中的身份證號與營業(yè)執(zhí)照信息,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2024-01-01Java實現(xiàn)讀取項目中文件(.json或.properties)的方法詳解
這篇文章主要為大家詳細介紹了Java實現(xiàn)讀取項目中文件的方法,例如.json或.properties,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-04-04啟動Tomcat報錯Unsupported major.minor version xxx的解決方法
這篇文章主要為大家詳細介紹了啟動Tomcat報錯Unsupported major.minor version xxx的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11SpringBoot整合EasyExcel實現(xiàn)Excel表格導出功能
這篇文章主要介紹了SpringBoot整合EasyExcel實現(xiàn)Excel表格導出功能,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-07-07