
知識改變命運(yùn),擼碼使我快樂,2020繼續(xù)游走在開源界
點(diǎn)贊再看,養(yǎng)成習(xí)慣
給我來個Star吧,點(diǎn)擊了解下基于SpringBoot的組件化接口服務(wù)落地解決方案
SpringBoot應(yīng)用程序在啟動時,我們可以傳遞自定義的參數(shù)來進(jìn)行動態(tài)控制邏輯,比如我們使用--debug啟動參數(shù)時就會使用debug啟動應(yīng)用程序,在控制臺打印一些調(diào)試日志信息。
推薦閱讀
什么是啟動項(xiàng)參數(shù)?
啟動項(xiàng)參數(shù)的格式一般是--開頭的,如:java -jar service.jar --debug --skip,啟動時我們就可以獲取[debug,skip]兩個啟動項(xiàng)參數(shù)。
SpringBoot 內(nèi)部提供了一個接口org.springframework.boot.ApplicationArguments來接收應(yīng)用程序在啟動時所傳遞的選項(xiàng)參數(shù)(Option Args),源碼如下所示:
public interface ApplicationArguments {
/**
* 返回未處理的原始參數(shù)列表
* @return the arguments
*/
String[] getSourceArgs();
/**
* 返回所有選項(xiàng)參數(shù)的名稱
* For example, if the arguments were
* "--foo=bar --debug" would return the values {@code ["foo", "debug"]}.
* @return the option names or an empty set
*/
Set<String> getOptionNames();
/**
* 根據(jù)選項(xiàng)參數(shù)名稱判斷是否在啟動時傳遞
* option with the given name.
* @param name the name to check
* @return {@code true} if the arguments contain an option with the given name
*/
boolean containsOption(String name);
/**
* 返回與具有給定名稱的arguments選項(xiàng)關(guān)聯(lián)的值的集合。
* <ul>
* <li>if the option is present and has no argument (e.g.: "--foo"), return an empty
* collection ({@code []})</li>
* <li>if the option is present and has a single value (e.g. "--foo=bar"), return a
* collection having one element ({@code ["bar"]})</li>
* <li>if the option is present and has multiple values (e.g. "--foo=bar --foo=baz"),
* return a collection having elements for each value ({@code ["bar", "baz"]})</li>
* <li>if the option is not present, return {@code null}</li>
* </ul>
* @param name the name of the option
* @return a list of option values for the given name
*/
List<String> getOptionValues(String name);
/**
* 返回分析的非選項(xiàng)參數(shù)的集合。
* @return the non-option arguments or an empty list
*/
List<String> getNonOptionArgs();
}
該接口有一個默認(rèn)的實(shí)現(xiàn)DefaultApplicationArguments,它實(shí)現(xiàn)了ApplicationArguments接口的全部定義方法。
DefaultApplicationArguments類在org.springframework.boot.SpringApplication#run(java.lang.String...)方法內(nèi)通過new進(jìn)行實(shí)例化,該對象實(shí)例主要用于啟動時的相關(guān)配置。
而在啟動過程中的org.springframework.boot.SpringApplication#prepareContext方法內(nèi)通過ConfigurableListableBeanFactory進(jìn)行注冊到IOC容器,并且把springApplicationArguments作為唯一名稱。
獲取啟動項(xiàng)參數(shù)
上面我們說道,在應(yīng)用啟動時會將ApplicationArguments接口的實(shí)現(xiàn)類實(shí)例注冊到IOC容器,所以我們可以使用注入ApplicationArguments接口的形式來獲取啟動項(xiàng)參數(shù),如下所示:
/**
* 加載啟動項(xiàng)參數(shù)
*
* @author 恒宇少年
*/
@Component
public class LoadArguments {
/**
* 構(gòu)造函數(shù)注入{@link ApplicationArguments}
*
* @param applicationArguments
*/
@Autowired
public LoadArguments(ApplicationArguments applicationArguments) {
// 判斷是否存在名為skip的啟動項(xiàng)參數(shù)
boolean isHaveSkip = applicationArguments.containsOption("skip");
System.out.println("skip:" + isHaveSkip);
// 遍歷輸出全部的非啟動項(xiàng)參數(shù)
List<String> arguments = applicationArguments.getNonOptionArgs();
for (int i = 0; i < arguments.size(); i++) {
System.out.println("非啟動項(xiàng)參數(shù):" + arguments.get(i));
}
}
}
我們把項(xiàng)目通過mvn package命令進(jìn)行打包后,使用如下命令啟動:
java -jar spring-boot-basic-accessing-application-arguments-0.0.1-SNAPSHOT.jar --skip noway
當(dāng)我們啟動后控制臺會輸出如下內(nèi)容:
...
skip:true
非啟動項(xiàng)參數(shù):noway
...
其中--skip為啟動項(xiàng)參數(shù),而后面攜帶的noway其實(shí)是不屬于skip啟動參數(shù),如果我們使用--skip=noway作為啟動參數(shù)時,調(diào)用ApplicationArguments#getOptionValues("skip")方法獲取到的值則是noway。
ApplicationRunner
除了通過注入ApplicationArguments的方式獲取啟動參數(shù)外,通過實(shí)現(xiàn)ApplicationRunner接口也可以獲取ApplicationArguments對象實(shí)例,使用方法如下所示:
/**
* {@link ApplicationRunner} 實(shí)現(xiàn)類
*
* @author 恒宇少年
*/
@Component
public class ApplicationRunnerSupport implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
boolean isHaveSkip = args.containsOption("skip");
System.out.println("skip:" + isHaveSkip);
System.out.println(args.getOptionValues("skip"));
}
}
注意事項(xiàng):實(shí)現(xiàn)
ApplicationRunner接口的類需要通過@Component標(biāo)注,通過注解方式注冊到IOC容器。
敲黑板,劃重點(diǎn)
我們可以通過注入、ApplicationRunner這兩種方法來獲取ApplicationArguments對象,那你知道這兩種方法的執(zhí)行先后順序嗎?帶著這個疑問可以動手實(shí)驗(yàn)下。
代碼示例
如果您喜歡本篇文章請為源碼倉庫點(diǎn)個Star,謝謝?。?!
本篇文章示例源碼可以通過以下途徑獲取,目錄為spring-boot-basic-accessing-application-arguments: