SpringBoot實現(xiàn)多個ApplicationRunner時部分接口未執(zhí)行問題
SpringBoot多個ApplicationRunner時部分接口未執(zhí)行
在springboot的項目中,需要在容器啟動之后執(zhí)行一些操作。springboot提供了ApplicationRunner和CommandLineRunner兩個接口可以幫助我們實現(xiàn)這種需求。
當(dāng)項目中實現(xiàn)了多個ApplicationRunner接口,并且其中一個使用了類似于while(true)這樣不會退出的循環(huán)體。將會導(dǎo)致后續(xù)的ApplicationRunner接口不會被調(diào)用。
如下:
@Component @Slf4j public class RunnerTest1 implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { while (true) { System.out.println("this is RunnerTest1"); Thread.sleep(100); } } }
@Component @Slf4j public class RunnerTest2 implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { while (true) { System.out.println("this is RunnerTest2"); Thread.sleep(100); } } }
輸出結(jié)果:
可以看到項目啟動后RunnerTest2 將不會被執(zhí)行。
通過分析springboot啟動的源碼可以發(fā)現(xiàn),在applicationContext容器加載完成之后,會調(diào)用SpringApplication類的callRunners方法
該方法中會獲取所有實現(xiàn)了ApplicationRunner和CommandLineRunner的接口bean,然后依次執(zhí)行對應(yīng)的run方法,并且是在同一個線程中執(zhí)行。
因此如果有某個實現(xiàn)了ApplicationRunner接口的bean的run方法一直循環(huán)不返回的話,后續(xù)的代碼將不會被執(zhí)行。
ApplicationRunner實現(xiàn)項目啟動就執(zhí)行的功能
ApplicationRunner
是一個接口,常用于項目啟動后,(也就是ApringApplication.run()執(zhí)行結(jié)束),立馬執(zhí)行某些邏輯。
可用于項目的準(zhǔn)備工作,比如加載配置文件,加載執(zhí)行流,定時任務(wù)等等。
如何使用ApplicationRunner
這里有幾點說明:
- 1:這個實現(xiàn)類,要注入到spring容器中,這里使用了@Component注解;
- 2:在同一個項目中,可以定義多個ApplicationRunner的實現(xiàn)類,他們的執(zhí)行順序通過注解@Order注解或者再實現(xiàn)Ordered接口來實現(xiàn)。
- 3:run方法的參數(shù):ApplicationArguments可以獲取到當(dāng)前項目執(zhí)行的命令參數(shù)。(比如把這個項目打成jar執(zhí)行的時候,帶的參數(shù)可以通過ApplicationArguments獲取到);
- 4:由于該方法是在容器啟動完成之后,才執(zhí)行的,所以,這里可以從spring容器中拿到其他已經(jīng)注入的bean。
(可以有多個實例實現(xiàn)該接口,但是一般需要增加注解@Order來指定加載順序)
@Component @Order(2) public class JDDRunner implements ApplicationRunner { ? ? @Override ? ? public void run(ApplicationArguments args) throws Exception { ? ? ? ? System.out.println(args); ? ? ? ? System.out.println("這個是測試ApplicationRunner接口"); ? ? } }
實現(xiàn)ApplicationRunner接口,重寫run方法,定義具體的執(zhí)行邏輯
@Order注解,用于決定多個bean的執(zhí)行順序,按照值從小到大執(zhí)行 (值可為負(fù)數(shù))
- @Order(-1)優(yōu)先于@Order(0)
- @Order(1)優(yōu)先于@Order(2)
還有個接口
也可以實現(xiàn)和ApplicationRunner一樣的功能
- CommandLineRunner
- CommandLineRunner接口的run方法接收的參數(shù)為String數(shù)組
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中FilterInputStream和FilterOutputStream的用法詳解
這篇文章主要介紹了Java中FilterInputStream和FilterOutputStream的用法詳解,這兩個類分別用于封裝輸入和輸出流,需要的朋友可以參考下2016-06-06