使用Spring事件機(jī)制實(shí)現(xiàn)異步的方法
當(dāng)把一個(gè)事件發(fā)布到Spring提供的ApplicationContext中,被監(jiān)聽(tīng)器偵測(cè)到,就會(huì)執(zhí)行對(duì)應(yīng)的處理方法。
事件本身
事件是一個(gè)自定義的類(lèi),需要繼承Spring提供的ApplicationEvent
。
@Data public class MyEvent extends ApplicationEvent { private String msg; public MyEvent(Object source, String msg) { super(source); this.msg = msg; } }
事件監(jiān)聽(tīng)
基本方法是實(shí)現(xiàn)ApplicationListener
接口,自定義一個(gè)監(jiān)聽(tīng)器,實(shí)現(xiàn)onApplicationEvent()
方法,然后添加到ApplicationContext
。
比如:
public class MyListener implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent event) { System.out.print("監(jiān)聽(tīng)到MyEvent事件"); } } ... // SpringBoot的啟動(dòng)類(lèi)中添加監(jiān)聽(tīng)器 public static void main(String[] args) { SpringApplication application = new SpringApplication(MyApplication.class); application.addListeners(new MyListener()); application.run(args); }
也可以使用注解@EventListener
(推薦):原理就是通過(guò)掃描這個(gè)注解,創(chuàng)建監(jiān)聽(tīng)器并添加到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ā)布
可以通過(guò)上下文對(duì)象的發(fā)布方法ConfigurableApplicationContext::publishEvent()
來(lái)發(fā)布。
也可以實(shí)現(xiàn)ApplicationEventPublisherAware
接口來(lái)發(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"; } }
測(cè)試代碼
@SpringBootTest @RunWith(SpringRunner.class) public class EventServiceTest { @Autowired private EventService service; @Test public void eventTest() { String msg="Java Code"; service.doEventWork(msg); } }
注意
如果2個(gè)事件之間是繼承關(guān)系,會(huì)先監(jiān)聽(tīng)到子類(lèi)事件,處理完再監(jiān)聽(tīng)父類(lèi)。
// 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(); } } }
當(dāng)我publish一個(gè)子類(lèi)事件MyEvent2時(shí),日志如下:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot整合RabbitMQ及生產(chǎn)全場(chǎng)景高級(jí)特性實(shí)戰(zhàn)
本文主要介紹了SpringBoot整合RabbitMQ及生產(chǎn)全場(chǎng)景高級(jí)特性實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10java 如何把byte轉(zhuǎn)化為KB、MB、GB的方法
這篇文章主要介紹了java 如何把byte轉(zhuǎn)化為KB、MB、GB的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10SpringBoot實(shí)現(xiàn)識(shí)別圖片中的身份證號(hào)與營(yíng)業(yè)執(zhí)照信息
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何實(shí)現(xiàn)識(shí)別圖片中的身份證號(hào)與營(yíng)業(yè)執(zhí)照信息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2024-01-01Java實(shí)現(xiàn)讀取項(xiàng)目中文件(.json或.properties)的方法詳解
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)讀取項(xiàng)目中文件的方法,例如.json或.properties,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-04-04Spring中實(shí)現(xiàn)定時(shí)調(diào)度的幾種方法
本篇文章主要介紹了Spring中實(shí)現(xiàn)定時(shí)調(diào)度示例,可以在無(wú)人值守的時(shí)候系統(tǒng)可以在某一時(shí)刻執(zhí)行某些特定的功能,有興趣的可以了解一下。2017-02-02啟動(dòng)Tomcat報(bào)錯(cuò)Unsupported major.minor version xxx的解決方法
這篇文章主要為大家詳細(xì)介紹了啟動(dòng)Tomcat報(bào)錯(cuò)Unsupported major.minor version xxx的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11SpringBoot整合EasyExcel實(shí)現(xiàn)Excel表格導(dǎo)出功能
這篇文章主要介紹了SpringBoot整合EasyExcel實(shí)現(xiàn)Excel表格導(dǎo)出功能,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-07-07