解讀CommandLineRunner或者ApplicationRunner接口
前言
CommandLineRunner、ApplicationRunner 接口是在容器啟動成功后的最后一步回調(diào)(類似開機自啟動)。
CommandLineRunner接口

CommandLineRunner
官方doc:
Interface used to indicate that a bean should run when it is contained within a SpringApplication. Multiple CommandLineRunner beans can be defined within the same application context and can be ordered using the Ordered interface or Order @Order annotation.
接口被用作將其加入spring容器中時執(zhí)行其run方法。多個CommandLineRunner可以被同時執(zhí)行在同一個spring上下文中并且執(zhí)行順序是以order注解的參數(shù)順序一致。
If you need access to ApplicationArguments instead of the raw String array
consider using ApplicationRunner.
如果你需要訪問ApplicationArguments去替換掉字符串數(shù)組,可以考慮使用ApplicationRunner類。
先看一個demo:
定義一個ServerStartedReport實現(xiàn)CommandLineRunner,并納入到srping容器中進行處理
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class ServerStartedReport implements CommandLineRunner{
@Override
public void run(String... args) throws Exception {
System.out.println("===========ServerStartedReport啟動====="+ LocalDateTime.now());
}
}定義一個ServerSuccessReport實現(xiàn)CommandLineRunner,并納入到spring容器處理
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Order(1)
@Component
public class ServerSuccessReport implements CommandLineRunner{
@Override
public void run(String... args) throws Exception {
System.out.println("=====應(yīng)用已經(jīng)成功啟動====="+ Arrays.asList(args));
}
}啟動類測試,也可以直接在spring容器訪問該值,
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
ApplicationArguments applicationArguments = context.getBean(ApplicationArguments.class);
System.out.println("============");
System.out.println("name="+applicationArguments.getOptionNames());
System.out.println("values===="+applicationArguments.getOptionValues("developer.name"));
}
}配置參數(shù),然后執(zhí)行啟動類

打印結(jié)果

ApplicationRunner接口

發(fā)現(xiàn)二者的官方j(luò)avadoc一樣,區(qū)別在于接收的參數(shù)不一樣。CommandLineRunner的參數(shù)是最原始的參數(shù),沒有做任何處理。ApplicationRunner的參數(shù)是ApplicationArguments,是對原始參數(shù)做了進一步的封裝。
ApplicationArguments是對參數(shù)(main方法)做了進一步的處理,可以解析--name=value的,我們就可以通過name來獲取value(而CommandLineRunner只是獲取--name=value)

可以接收--foo=bar這樣的參數(shù)。
--getOptionNames()方法可以得到foo這樣的key的集合。--getOptionValues(String name)方法可以得到bar這樣的集合的value。
看一個demo:
定義MyApplicationRunner類繼承ApplicationRunner接口:
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
public class MyApplicationRunner implements ApplicationRunner{
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("===MyApplicationRunner==="+ Arrays.asList(args.getSourceArgs()));
System.out.println("===getOptionNames========"+args.getOptionNames());
System.out.println("===getOptionValues======="+args.getOptionValues("foo"));
System.out.println("==getOptionValues========"+args.getOptionValues("developer.name"));
}
}啟動類:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}配置參數(shù)啟動:

打印結(jié)果:

總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

