javascript
docker启动后自动退出_Spring Boot项目启动后如何自动执行逻辑
1. 前言
不知道你有沒(méi)有接到這種需求,項(xiàng)目啟動(dòng)后立馬執(zhí)行一些邏輯。比如簡(jiǎn)單的緩存預(yù)熱,或者上線后的廣播之類等等。如果你使用 Spring Boot 框架的話就可以借助其提供的接口CommandLineRunner和 ApplicationRunner來(lái)實(shí)現(xiàn)。
2. CommandLineRunner
org.springframework.boot.CommandLineRunner 是Spring Boot提供的一個(gè)接口,當(dāng)你實(shí)現(xiàn)該接口并將之注入Spring IoC容器后,Spring Boot應(yīng)用啟動(dòng)后就會(huì)執(zhí)行其run方法。一個(gè)Spring Boot可以存在多個(gè)CommandLineRunner的實(shí)現(xiàn),當(dāng)存在多個(gè)時(shí),你可以實(shí)現(xiàn)Ordered接口控制這些實(shí)現(xiàn)的執(zhí)行順序(Order 數(shù)值越大優(yōu)先級(jí)越低)。接下來(lái)我們來(lái)聲明兩個(gè)實(shí)現(xiàn)并指定順序:
優(yōu)先執(zhí)行:
package?cn.felord;import?lombok.extern.slf4j.Slf4j;
import?org.springframework.boot.CommandLineRunner;
import?org.springframework.core.Ordered;
import?org.springframework.stereotype.Component;
/**
?*?優(yōu)先級(jí)最高
?*?該類期望在springboot?啟動(dòng)后第一順位執(zhí)行
?*?@author?felord.cn
?*?@since?12:57
?**/
@Slf4j
@Component
public?class?HighOrderCommandLineRunner?implements?CommandLineRunner,?Ordered?{
????@Override
????public?void?run(String...?args)?throws?Exception?{
????????for?(String?arg?:?args)?{
????????????log.info("arg?=?"?+?arg);
????????}
????????log.info("i?am?highOrderRunner");
????}
????@Override
????public?int?getOrder()?{
????????return?Integer.MIN_VALUE+1;
????}
}
第二順序執(zhí)行:
package?cn.felord;import?lombok.extern.slf4j.Slf4j;
import?org.springframework.boot.CommandLineRunner;
import?org.springframework.core.Ordered;
import?org.springframework.stereotype.Component;
/**
?*?優(yōu)先級(jí)低于{@code?HighOrderCommandLineRunner}
?*?@author?felord.cn
?*?@since?12:59
?**/
@Slf4j
@Component
public?class?LowOrderCommandLineRunner?implements?CommandLineRunner,?Ordered?{
????@Override
????public?void?run(String...?args)?throws?Exception?{
????????log.info("i?am?lowOrderRunner");
????}
????@Override
????public?int?getOrder()?{
????????return?Integer.MIN_VALUE+1;
????}
}
然后啟動(dòng)Spring Boot應(yīng)用后,控制臺(tái)按照預(yù)定的順序打印出了結(jié)果:
2020-05-30 23:11:03.685 INFO 11976 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''2020-05-30 23:11:03.701 INFO 11976 --- [ main] c.f.Application : Started SpringBootApplication in 4.272 seconds (JVM running for 6.316)
2020-05-30 23:11:03.706 INFO 11976 --- [ main] c.f.HighOrderCommandLineRunner : i am highOrderRunner
2020-05-30 23:11:03.706 INFO 11976 --- [ main] c.f.LowOrderCommandLineRunner : i am lowOrderRunner
3. ApplicationRunner
在Spring Boot 1.3.0又引入了一個(gè)和CommandLineRunner功能一樣的接口ApplicationRunner。CommandLineRunner接收可變參數(shù)String... args,而ApplicationRunner 接收一個(gè)封裝好的對(duì)象參數(shù)ApplicationArguments。除此之外它們功能完全一樣,甚至連方法名都一樣。聲明一個(gè)ApplicationRunner并讓它優(yōu)先級(jí)最低:
package?cn.felord;import?lombok.extern.slf4j.Slf4j;
import?org.springframework.boot.ApplicationArguments;
import?org.springframework.boot.ApplicationRunner;
import?org.springframework.core.Ordered;
import?org.springframework.stereotype.Component;
import?java.util.Arrays;
import?java.util.List;
import?java.util.Set;
/**
?*?優(yōu)先級(jí)最低
?*?@author?felord.cn
?*?@since?13:00
?**/
@Slf4j
@Component
public?class?DefaultApplicationRunner?implements?ApplicationRunner,?Ordered?{
????@Override
????public?void?run(ApplicationArguments?args)?throws?Exception?{
????????log.info("i?am?applicationRunner");
????????Set?optionNames?=?args.getOptionNames();
????????log.info("optionNames?=?"?+?optionNames);
????????String[]?sourceArgs?=?args.getSourceArgs();
????????log.info("sourceArgs?=?"?+?Arrays.toString(sourceArgs));
????????List?nonOptionArgs?=?args.getNonOptionArgs();
????????log.info("nonOptionArgs?=?"?+?nonOptionArgs);
????????List?optionValues?=?args.getOptionValues("foo");
????????log.info("optionValues?=?"?+?optionValues);
????}@Overridepublic?int?getOrder()?{return?Integer.MIN_VALUE+2;
????}
}
按照順序打印了三個(gè)類的執(zhí)行結(jié)果:
2020-06-01 13:02:39.420 INFO 19032 --- [ main] c.f.MybatisResultmapApplication : Started MybatisResultmapApplication in 1.801 seconds (JVM running for 2.266)2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.HighOrderCommandLineRunner : i am highOrderRunner
2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.LowOrderCommandLineRunner : i am lowOrderRunner
2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : i am applicationRunner
2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : optionNames = []
2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : sourceArgs = []
2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : nonOptionArgs = []
2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : optionValues = null
Ordered接口并不能被 @Order注解所代替。
4. 傳遞參數(shù)
相信很多同學(xué)看到這里都開始對(duì)這兩個(gè)run方法的入?yún)⒏信d趣了。Spring Boot應(yīng)用啟動(dòng)時(shí)是可以接受參數(shù)的,換句話說(shuō)也就是Spring Boot的main方法是可以接受參數(shù)的。這些參數(shù)通過(guò)命令行 java -jar yourapp.jar 來(lái)傳遞。CommandLineRunner會(huì)原封不動(dòng)照單全收這些接口,這些參數(shù)也可以封裝到ApplicationArguments對(duì)象中供ApplicationRunner調(diào)用。我們來(lái)認(rèn)識(shí)一下ApplicationArguments的相關(guān)方法:
getSourceArgs() 被傳遞給應(yīng)用程序的原始參數(shù),返回這些參數(shù)的字符串?dāng)?shù)組。
getOptionNames() 獲取選項(xiàng)名稱的Set字符串集合。如 --spring.profiles.active=dev --debug 將返回["spring.profiles.active","debug"] 。
getOptionValues(String name) 通過(guò)名稱來(lái)獲取該名稱對(duì)應(yīng)的選項(xiàng)值。如--foo=bar --foo=baz 將返回["bar","baz"]。
containsOption(String name) 用來(lái)判斷是否包含某個(gè)選項(xiàng)的名稱。
getNonOptionArgs() 用來(lái)獲取所有的無(wú)選項(xiàng)參數(shù)。
接下來(lái)我們?cè)囼?yàn)一波,你可以通過(guò)下面的命令運(yùn)行一個(gè) Spring Boot應(yīng)用 Jar
或者在IDEA開發(fā)工具中打開Spring Boot應(yīng)用main方法的配置項(xiàng),進(jìn)行如下配置,其他IDE工具同理。
運(yùn)行Spring Boot應(yīng)用,將會(huì)打印出:
2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = --foo=bar2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = --foo=baz
2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = --dev.name=碼農(nóng)小胖哥
2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = java
2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = felordcn
2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : i am highOrderRunner
2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.LowOrderCommandLineRunner : i am lowOrderRunner
2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : i am applicationRunner
2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : optionNames = [dev.name, foo]
2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : sourceArgs = [--foo=bar, --foo=baz, --dev.name=碼農(nóng)小胖哥, java, felordcn]
2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : nonOptionArgs = [java, felordcn]
2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : optionValues = [bar, baz]
然后你就可以根據(jù)實(shí)際需要?jiǎng)討B(tài)地執(zhí)行一些邏輯。
5. 總結(jié)
今天我們對(duì)CommandLineRunner和ApplicationRunner進(jìn)行了講解,從用法到順序執(zhí)行,又對(duì)Spring Boot傳遞參數(shù)進(jìn)行了介紹和演示,希望對(duì)你有所幫助。多多關(guān)注:碼農(nóng)小胖哥,更多編程干貨分享給你。
往期推薦:
寫著寫著代碼就被帶上了警車
Java設(shè)計(jì)模式之命令模式
總結(jié)
以上是生活随笔為你收集整理的docker启动后自动退出_Spring Boot项目启动后如何自动执行逻辑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python数据类型怎么定义_零基础如何
- 下一篇: wav音量和分贝转换关系_电吉他音箱瓦数