Spring Boot 中的 ApplicationRunner 和 CommandLineRunner
Spring Boot Java About 3,347 words介绍
ApplicationRunner
和CommandLineRunner
两个runner
都是在Spring Boot
程序初始化完成后调用,可以做一些业务的初始化等。
一次性脚本也可以直接写在在runner
中。
异同
ApplicationRunner
和CommandLineRunner
都可以命令行参数。
java -jar xxx.jar arg1 --foo=value1,value2 arg2
同步线程执行完成后再执行下一个runner
,等所有线程(包括子线程)执行完毕后才退出程序。
ApplicationRunner
将参数封装为操作参数与非操作参数。--foo
为操作参数,arg1
为非操作参数。
@Order(1)
@Component
public class TestApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
//ApplicationRunner running, args#[arg1, arg2, --foo=value,value2]
System.out.println("ApplicationRunner running, args#" + Arrays.asList(args.getSourceArgs()));
List<String> nonOptionArgs = args.getNonOptionArgs();
//non option args#[arg1, arg2]
System.out.println("non option args#" + nonOptionArgs);
List<String> foo = args.getOptionValues("foo");
//option args#[value,value2]
System.out.println("option args#" + foo);
List<String> foo2 = args.getOptionValues("foo2");
//not exist option args#null
System.out.println("not exist option args#" + foo2);
Thread.sleep(5000);
new Thread(() -> {
try {
Thread.sleep(5000);
System.out.println("ApplicationRunner sub thread, threadId#" + Thread.currentThread().getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
CommandLineRunner
统一将参数读取为一个字符串,需自己解析。
@Order(2)
@Component
public class TestCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
//CommandLineRunner running, args#[arg1, arg2, --foo=value,value2], threadId#1
System.out.println("CommandLineRunner running, args#" + Arrays.asList(args) + ", threadId#" + Thread.currentThread().getId());
new Thread(() -> {
try {
Thread.sleep(5000);
//CommandLineRunner sub thread, threadId#30
System.out.println("CommandLineRunner sub thread, threadId#" + Thread.currentThread().getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
源码
在SpringApplication.run
中的callRunners
按@Order
升序依次遍历运行。
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}
private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
try {
(runner).run(args);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
}
}
代码
Views: 3,683 · Posted: 2020-04-07
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...