SpringBoot定義系統啓動任務,你會幾種?

一、前言

很久很久以前,在 servlet / jsp 項目中,如果是涉及到系統啓動任務,例如:在項目剛啓動的時候進行一些數據初始化操作,這類操作都有着一個共性,那就是隻在項目剛啓動時執行一次,後面不再執行。

當然,那些經歷過 servlet / jsp 的朋友,腦袋立馬能浮現Web基礎中的三大組件(Servlet、Filter、Listener)中的Listener(監聽器)。一般情況,定義一個ServletContextListener,便可以監聽到項目的啓動、銷燬,這樣方便對數據進行初始化、銷燬操作。如下:

public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //啓動後執行,在這裏做數據初始化操作
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //銷燬前執行,可以在這裏做數據備份操作
    }
}

上面提到只是基礎的Web項目解決方案,現在使用了SpringBoot項目,這種操作更簡單了。在SpringBoot項目中,針對定義系統啓動任務,提供了兩種方案,分別是:CommandLineRunnerApplicationRunner

接下來,就分別來看看這兩種解決方案。

二、CommandLineRunner

首先,我們創建一個MyCommandLineRunner01類,並且實現CommandLineRunner接口,如下:

@Component
@Order(100)
public class MyCommandLineRunner01 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.err.println("MyCommandLineRunner01>>>" + Arrays.toString(args));
    }
}

下面,就對這段代碼進行說明,如下:

  1. @Component註解:表示將MyCommandLineRunner01類註冊成爲Spring容器中的一個Bean。
  2. @Order註解:表示該啓動任務的執行優先級,因爲,在一個項目中,可能存在着多個啓動任務,所以需要定義優先級。@Order註解中的整數值越小,優先級越高,默認值是Integer_MAXVALUE,表示優先級最低。
  3. run方法中,是用來寫啓動任務的核心業務邏輯的,啓動項目時,run方法會被執行。
  4. run方法中的參數,來自於項目的啓動參數,即項目啓動類中main方法的參數會被傳遞到此。

命令行啓動項目

另一種傳參方式,是先將項目打包,使用命令行啓動項目時,並傳入參數,如下:

java -jar commandlinerunner-0.0.1-SNAPSHOT.jar 武漢加油 中國加油

值得注意的是,這裏傳參沒有key,只有value,所以多個value用空格隔開即可,運行結果如下:
在這裏插入圖片描述

三、ApplicationRunner

其實,CommandLineRunnerApplicationRunner的功能相同,用法也相同,唯一的區別主要體現在對參數的處理上,ApplicationRunner可以接收更多類型的參數(ApplicationRunner除了可以接收CommandLineRunner中類型的參數外,還能接收key-value形式的參數)。

使用ApplicationRunner除了實現的接口不同之外,其他用法和CommandLineRunner都是一樣的,如下:

@Component
@Order(100)
public class MyApplicationRunner01 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        String[] sourceArgs = args.getSourceArgs();
        System.err.println("sourceArgs>>>"+ Arrays.toString(sourceArgs));
        List<String> nonOptionArgs = args.getNonOptionArgs();
        System.err.println("nonOptionArgs>>>"+nonOptionArgs);
        Set<String> optionNames = args.getOptionNames();
        System.err.println(">>>>>>>>>>>>>>>>MyApplicationRunner01開始>>>>>>>>>>>>>>>>>");
        for (String optionName : optionNames) {
            System.err.println(optionName+":"+args.getOptionValues(optionName));
        }
        System.err.println(">>>>>>>>>>>>>>>>>MyApplicationRunner01結束>>>>>>>>>>>>>>>>");
    }
}

CommandLineRunnerrun方法相同,都是在項目啓動時被執行,但是不同的是run方法的參數,關於ApplicationArguments參數,可以來看看該類型的參數中有哪些方法,作用分別是什麼?

  1. args.getSourceArgs():表示獲取所有的參數。
  2. args.getNonOptionArgs():表示獲取參數中非key-value的參數(與CommandLineRunner中相同)。
  3. args.getOptionNames():表示獲取參數中key-value形式的參數的key。
  4. args.getOptionValues():表示獲取參數中key-value形式的參數的value。

ApplicationArguments定義完成後,傳啓動參數也是兩種方式,非key-value形式的參數和CommandLineRunner中相同,對於key-value形式的參數,IDEA中如此定義,如下:

java -jar applicationrunner-0.0.1-SNAPSHOT.jar --name=mango --address=www.mango.com 武漢加油 中國加油

注意,這裏的key-value形式的參數格式爲:--key=value,非key-value形式參數與CommandLineRunner中相同,運行結果如下:
在這裏插入圖片描述

四、總結

經過兩種方式的實踐,可以看出兩者之間主要在於對參數的處理不同,ApplicationRunner > CommandLineRunner,至於如何選擇,就看項目中具體的需求了。

五、源碼地址

CommandLineRunner源碼地址:CommandLineRunner
ApplicationRunner源碼地址:ApplicationRunner

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章