1. ApplicationRunner接口
用法:
-
類型: 接口
-
方法: 只定義了一個run方法
-
使用場景: springBoot項目啟動時,若想在啟動之后直接執行某一段代碼,就可以用 ApplicationRunner這個接口,并實現接口里面的run(ApplicationArguments args)方法,方法中寫上自己的代碼邏輯。也就是:spring容器啟動完成之后,就會緊接著執行這個接口實現類的run方法。
-
run方法的參數: ApplicationArguments可以獲取到當前項目執行的命令參數。(比如把這個項目打成jar執行的時候,帶的參數可以通過ApplicationArguments獲取到);
@Component //此類一定要交給spring管理
public class ConsumerRunner implements ApplicationRunner{@Overridepublic void run(ApplicationArgumers args) throws Exception{//代碼System.out.println("需要在springBoot項目啟動時執行的代碼---");}
}
若有多個代碼段需要執行,可用@Order注解設置執行的順序。
在同一個項目中,可以定義多個ApplicationRunner的實現類,他們的執行順序通過注解@Order注解或者再實現Ordered接口來實現。
@Order注解: 如果有多個實現類,而你需要他們按一定順序執行的話,可以在實現類上加上@Order注解。@Order(value=整數值)。SpringBoot會按照@Order中的value值從小到大依次執行。
@order, 使用注解方式使bean的加載順序得到控制;@Order標記定義了組件的加載順序,值越小擁有越高的優先級,可為負數。值越小,越先被加載。
@Order(-1) 優先于 @Order(0)
@Order(1) 優先于 @Order(2)
@Component //此類一定要交給spring管理
@Order(value=1) //首先執行
public class ConsumerRunnerA implements ApplicationRunner{@Overridepublic void run(ApplicationArgumers args) throws Exception{//代碼System.out.println("需要在springBoot項目啟動時執行的代碼1---");}
}
@Component //此類一定要交給spring管理
@Order(value=2) //其次執行
public class ConsumerRunnerB implements ApplicationRunner{@Overridepublic void run(ApplicationArgumers args) throws Exception{//代碼System.out.println("需要在springBoot項目啟動時執行的代碼2---");}
}
@Component注解: 將類注入到spring容器中。
參考鏈接:https://blog.csdn.net/hc1285653662/article/details/122445495
2. CommandLineRunner接口
用法:
在容器啟動成功后的最后一步回調(類似開機自啟動)
寫一個類,實現CommandLineRunner接口,將該類注入到Spring容器中;
可以通過@Order注解(屬性指定數字越小表示優先級越高)或者Ordered接口來控制執行順序。
EX:自定義兩個類,實現CommandLineRunner接口,實現run方法,在run方法中添加處理邏輯。
@Order(5)
@Component
public class AppStartReport implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("AppStartReport : 項目成功啟動------------------");}
}
@Order(2)
@Component
public class AppStartReport2 implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("AppStartReport2 : 項目成功啟動------------------");}
}
啟動效果:AppStartReport2 較AppStartReport 先執行:
3. ApplicationRunner接口與CommandLineRunner接口的區別
區別:
- CommandLineRunner的方法參數是原始的參數,未做任何處理;
- ApplicationRunner的參數為ApplicationArguments對象,是對原始參數的進一步封裝。ApplicationArguments是對參數(主要針對main方法)做了進一步的處理,可以解析–name=value的參數,我們就可根據name獲取value。
@Component
public class AppStartReport3 implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("AppStartReport3 : 項目成功啟動,參數為: " + Arrays.asList(args.getSourceArgs()));}
}
@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication application = new SpringApplication(App.class);ConfigurableApplicationContext context = application.run("aaa", "bbb");context.close();}
}
自行指定參數后,執行效果如下:
也可以在Program arguments選項框設置初始值,“–key=value“形式,如“–argname=ccc”,如下圖所示:
@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication application = new SpringApplication(App.class);ConfigurableApplicationContext context = application.run(args);context.close();}
}
啟動器傳入參數為main方法的參數args,效果如下:
ApplicationArguments 源碼分析
public interface ApplicationArguments {String[] getSourceArgs();Set<String> getOptionNames();boolean containsOption(String name);List<String> getOptionValues(String name);List<String> getNonOptionArgs();}
資源參數分為兩種,一種是在調用run方法時傳入的(”aaa”,”bbb”),一種是配置的系統參數即main方法的args參數(”ccc”)。
-
首先getSourceArgs方法,可以獲取到所有參數,可以是自己傳入的參數,也可以是配置的系統參數;
-
getNonOptionArgs方法即可獲得我們傳入的參數(”aaa”,”bbb”)。;
-
其余3個方法,可獲得系統參數。實際用法如下:
EX:
@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication application = new SpringApplication(App.class);ConfigurableApplicationContext context = application.run(args);ApplicationArguments arguments = context.getBean(ApplicationArguments.class);System.out.println("參數個數:" + arguments.getSourceArgs().length);System.out.println("Non OptionArgs:" + arguments.getNonOptionArgs());System.out.println("Option Names:" + arguments.getOptionNames());System.out.println("獲取key為argname的value值:" + arguments.getOptionValues("argname"));System.out.println("是否包含key為argname的參數:" + arguments.containsOption("argname"));context.close();}
}
輸出效果:
參考鏈接:https://blog.csdn.net/qq_35006663/article/details/102264172