使用启动加载器
实现CommandLineRunner 接口
@Order(1)
@Component
public class FirstCommandlineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("=========FirstCommandlineRunner=============");}
}
实现ApplicationRunner 接口
@Order(1)
@Component
public class SecondApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("=========SecondApplicationRunner=============");}
}
两种实现方式比较
相同点
-
调用点一样
都是在callRunners中调用
-
实现方法名一样
都是通过实现接口来重写run方法
-
通过Order来决定实现顺序
差异点
- 执行优先级差异,第二种 > 第一种
- run方法入参不一致
CommandLineRunner 实现run传入String… args
ApplicationRunner 实现run传入ApplicationArguments args
执行结果
有执行结果可以看出,两种实现方式的Order一样,但是第二种的执行顺序早于第一种执行顺序,为什么会是这样的执行顺序,继续往下看
原理解析
run()方法中调用:callRunners
private void callRunners(ApplicationContext context, ApplicationArguments args) {List<Object> runners &#61; 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);}}
}
- 在方法中首先获得ApplicationRunner和CommandLineRunner接口的实现类&#xff0c;然后对runners进行排序&#xff0c;排序后遍历调用执行callRunner方法
- List runners &#61; new ArrayList<>(); 用的是object来装所有的Runner&#xff0c;在排序的时候对两种实现都采用Order注解排序&#xff0c;所以会对两种实现方式基于Order来排序
- 上面的两种实现方式&#xff0c;由于Order值一样都是1&#xff0c;但是runners.addAll()是添加ApplicationRunner接口实现对象&#xff0c;runners是个有序集合&#xff0c;所以第二种的执行顺序早于第一种
private void callRunner(ApplicationRunner runner, ApplicationArguments args) {try {(runner).run(args);}catch (Exception ex) {throw new IllegalStateException("Failed to execute ApplicationRunner", ex);}
}private void callRunner(CommandLineRunner runner, ApplicationArguments args) {try {(runner).run(args.getSourceArgs());}catch (Exception ex) {throw new IllegalStateException("Failed to execute CommandLineRunner", ex);}
}