新聞中心
[[410656]]
目錄
- 前言
- CommandLineRunner
- ApplicationRunner
- ApplicationListener
- @PostConstruct
- InitializationBean
- 總結(jié)
前言
我們經(jīng)常有一些業(yè)務(wù)需求,需要在項(xiàng)目啟動(dòng)后執(zhí)行相關(guān)的業(yè)務(wù)代碼,如:數(shù)據(jù)的初始化業(yè)務(wù)。今天我們來梳理一下有哪些方案?

梁平網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)于2013年創(chuàng)立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
CommandLineRunner
CommandLineRunner是一個(gè)接口,通過實(shí)現(xiàn)它,我們可以在Spring應(yīng)用成功啟動(dòng)之后執(zhí)行一些代碼片段
我們先定義個(gè)User實(shí)體Bean
下面我們定義一個(gè)類實(shí)現(xiàn)CommandLineRunner接口
當(dāng) Spring Boot 在應(yīng)用上下文中找到 CommandLineRunner bean,它將會(huì)在應(yīng)用成功啟動(dòng)之后調(diào)用 run() 方法,并傳遞用于啟動(dòng)應(yīng)用程序的命令行參數(shù)
java -jar demo-0.0.1-SNAPSHOT.jar --foo=bar --name=gujch
啟動(dòng)執(zhí)行結(jié)果
小結(jié):
- 命令行傳入的參數(shù)并沒有被解析,而只是顯示出我們傳入的字符串內(nèi)容 --foo=bar,--name=gujch
- 在重寫的 run() 方法上有 throws Exception 標(biāo)記,Spring Boot 會(huì)將 CommandLineRunner 作為應(yīng)用啟動(dòng)的一部分,如果運(yùn)行 run() 方法時(shí)拋出 Exception,應(yīng)用將會(huì)終止啟動(dòng)
- 當(dāng)有多個(gè) CommandLineRunner 時(shí),將會(huì)按照 @Order 注解中的數(shù)字從小到大
如果我們只是想簡單的獲取以空格分隔的命令行參數(shù),那 MyCommandLineRunner 就足夠使用了
ApplicationRunner
上面提到,通過命令行啟動(dòng)并傳遞參數(shù),MyCommandLineRunner 不能解析參數(shù),如果要解析參數(shù),那我們就要用到 ApplicationRunner 參數(shù)了
執(zhí)行結(jié)果
到這里我們可以看出:
同 MyCommandLineRunner 相似,但 ApplicationRunner 可以通過 run 方法的 ApplicationArguments 對象解析出命令行參數(shù),并且每個(gè)參數(shù)可以有多個(gè)值在里面,因?yàn)?getOptionValues 方法返回 List數(shù)組
在重寫的 run() 方法上有 throws Exception 標(biāo)記,Spring Boot 會(huì)將 ApplicationRunner 作為應(yīng)用啟動(dòng)的一部分,如果運(yùn)行 run() 方法時(shí)拋出 Exception,應(yīng)用將會(huì)終止啟動(dòng)
ApplicationRunner 也可以使用 @Order 注解進(jìn)行排序,從啟動(dòng)結(jié)果來看,它與 CommandLineRunner 共享 order 的順序
我們來看看源碼,CommandLineRunner 和 ApplicationRunner 是在何時(shí)被調(diào)用的呢?
SpringApplication.java類中callRunners方法
上面可以看到spring獲取CommandLineRunner 和 ApplicationRunner Bean會(huì)放到List中,然后一起排序,所以@Order排序是共享的
ApplicationListener
如果我們不需要獲取命令行參數(shù)時(shí),我們可以將啟動(dòng)邏輯綁定到 Spring 的 ApplicationReadyEvent 上
執(zhí)行結(jié)果
ApplicationReadyEvent 當(dāng)且僅當(dāng) 在應(yīng)用程序就緒之后才被觸發(fā)。
啟動(dòng)順序Order不與CommandLineRunner和ApplicationRunner共享
如果我們不需要獲取命令行參數(shù),我們可以通過 ApplicationListener 創(chuàng)建一些全局的啟動(dòng)邏輯,我們還可以通過它獲取 Spring Boot 支持的 configuration properties 環(huán)境變量參數(shù) ,因?yàn)閑vent參數(shù)有configuration上下文
@PostConstruct
創(chuàng)建啟動(dòng)邏輯的另一種簡單解決方案是提供一種在 bean 創(chuàng)建期間由 Spring 調(diào)用的初始化方法。我們要做的就只是將 @PostConstruct 注解添加到方法中:
執(zhí)行結(jié)果
從上面運(yùn)行結(jié)果可以看出:
1)Spring 創(chuàng)建完 bean之后 (在啟動(dòng)之前),便會(huì)立即調(diào)用 @PostConstruct 注解標(biāo)記的方法,因此我們無法使用 @Order 注解對其進(jìn)行自由排序,因?yàn)樗赡芤蕾囉?@Autowired插入到我們 bean 中的其他 Spring bean。
2)相反,它將在依賴于它的所有 bean 被初始化之后被調(diào)用
@PostConstruct 方法固有地綁定到現(xiàn)有的 Spring bean,因此應(yīng)僅將其用于此單個(gè) bean 的初始化邏輯;
@PostConstruct應(yīng)用場景:
在生成對象時(shí)候做一些初始化操作,而這些初始化操作又依賴于依賴注入(populateBean),那么就無法在構(gòu)造函數(shù)中實(shí)現(xiàn)。這時(shí),可以使用@PostConstruct注解一個(gè)方法來完成初始化,@PostConstruct注解的方法將會(huì)在依賴注入完成后被自動(dòng)調(diào)用。
InitializingBean
與 @PostConstruct 解決方案非常相似,我們可以實(shí)現(xiàn) InitializingBean 接口,并讓 Spring 調(diào)用某個(gè)初始化方法:
執(zhí)行結(jié)果
@PostConstruct 和 afterPropertiesSet 區(qū)別
1、afterPropertiesSet,顧名思義「在屬性設(shè)置之后」,調(diào)用該方法時(shí),該 bean 的所有屬性已經(jīng)被 Spring 填充。如果我們在某些屬性上使用 @Autowired(常規(guī)操作應(yīng)該使用構(gòu)造函數(shù)注入),那么 Spring 將在調(diào)用afterPropertiesSet 之前將 bean 注入這些屬性。但 @PostConstruct 并沒有這些屬性填充限制
2、所以
InitializingBean.afterPropertiesSet 解決方案比使用 @PostConstruct 更安全,因?yàn)槿绻覀円蕾嚿形醋詣?dòng)注入的 @Autowired 字段,則 @PostConstruct 方法可能會(huì)遇到 NullPointerExceptions
總結(jié)
從上面的例子中我們就可以發(fā)現(xiàn)各個(gè)啟動(dòng)方案的順序
針對Bean實(shí)體啟動(dòng)初始化 順序
Construct >> @Autowired(依賴注入) >> @postConstruct >> InitializingBean
針對整體項(xiàng)目啟動(dòng) 順序
CommandLineRunner和ApplicationRunner >> ApplicationListener
網(wǎng)站欄目:Spring多種啟動(dòng)初始化方案,看這篇就夠了
分享鏈接:http://m.fisionsoft.com.cn/article/dpscpph.html


咨詢
建站咨詢
