SpringBoot2.x基礎(chǔ)篇:應(yīng)用程序在啟動時訪問啟動項(xiàng)參數(shù)

知識改變命運(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

作者個人 博客
使用開源框架 ApiBoot 助你成為Api接口服務(wù)架構(gòu)師

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容