9. CommandLineRunner与Application
2019-08-09 本文已影响0人
光小月
实际应用中,我们会有在项目服务启动的时候就去加载一些数据或做一些事情这样的需求。
spring boot 提供了 两个接口, CommandLineRunner, ApplicationRunner
只要实现这两个接口,就可以实现在项目启动的时候,加载一些数据
栗子
@Component
public class MyStartupRunner1 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println(">>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作<<<<<<<<<<<<<");
}
}
@Component
@Order(value=2)
public class MyStartupRunner1 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println(">>>>>>>>>>>>>>>服务启动执行,执行加载数据等操作 11111111 <<<<<<<<<<<<<");
}
}
流程
系统启动之后,会将运行这两个类, @Order 用于规定加载顺序, 值越大先运行
底层分析
在spring boot 系统时,可以查看到除了主要创建了配置环境(environment)、事件监听(listeners)、应用上下文(applicationContext)之外,
还会运行一些Runner
在spring-boot:v2.0.9中的 SpringApplication.java中,在系统之后会运行一些Runner
public ConfigurableApplicationContext run(String... args) {
....
listeners.started(context);
// 运行Runner, 参数为上下文和系统传参
callRunners(context, applicationArguments);
...
}
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
// 将多个ApplicationRunner实例加入到list
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
// 将多个CommandLineRunner实例加入到list
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
// 通过这些实例的Order注解排序
AnnotationAwareOrderComparator.sort(runners);
// run
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}
CommandLineRunner与ApplicationRunner的区别
主要区别在于参数的类型,CommandLineRunner的参数是raw string array, 而ApplicationRunner的参数类型为ApplicationArguments, 这个需要自己构建这种类型
PS: 若你觉得可以、还行、过得去、甚至不太差的话,可以“关注”一下,就此谢过!