当我们希望在springboot容器后,执行一些操作的时候,我们可以考虑使用ApplicationRunner或者CommandLineRunner
问题:
- ApplicationRunner与CommandLineRunner谁先执行
- 两者的区别在哪
- 多个CommandLineRunner 执行顺序问题
1.ApplicationRunner与CommandLineRunner谁先执行。
我们在一个应用中分别实现两个接口
@Component public class CommandLineRunnerTest implements CommandLineRunner { @Override public void run(String... arg0) throws Exception { System.out.println("CommandLineRunner=====执行开始"); for (int i = 0; i < arg0.length; i++) { System.out.println(arg0[i]); } System.out.println("CommandLineRunner=====执行完毕"); } } 复制代码
@Component public class ApplicationRunnerTest implements ApplicationRunner { @Override public void run(ApplicationArguments arg0) throws Exception { System.out.println("ApplicationRunner=====执行开始"); System.out.println(arg0.getNonOptionArgs()); System.out.println(arg0.getOptionNames()); System.out.println("ApplicationRunner=====执行完成"); } } 复制代码
从执行结果来看,ApplicationRunner默认先于CommandLineRunner执行
ApplicationRunner=====执行开始 [] [name, age] [lisi] ApplicationRunner=====执行完成 CommandLineRunner=====执行开始 --name=lisi --age=12 CommandLineRunner=====执行完毕 复制代码
2.两者的区别,以及与main方法的联系
两个接口中都有run方法,负责接收来自应用外部的参数,ApplicationRunner的run方法会将外部参数封装成一个ApplicationArguments对象,而CommandLineRunner接口中run方法的参数则为String数组。
我们再回头看看main方法
@SpringBootApplication public class AliyunmqApplication { public static void main(String[] args) { System.out.println("main方法==========执行开始"); for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } System.out.println("main方法==========执行完毕"); SpringApplication.run(AliyunmqApplication.class, args); } } 复制代码
我们看到main方法也是接收一个args 数组参数。
执行发现:
main方法==========执行开始 --name=lisi --age=12 main方法==========执行完毕 .............. .............. ApplicationRunner=====执行开始 [] [name, age] [lisi] ApplicationRunner=====执行完成 CommandLineRunner=====执行开始 --name=lisi --age=12 CommandLineRunner=====执行完毕 复制代码
main方法的arg参数 和 CommandLineRunner方法的arg数组的值是一样的。
总的来看: ApplicationRunner run方法中的ApplicationArguments 对象,对输入参数做了封装,让我们可以使用 get**()的形式获取参数。CommandLineRunner run方法的arg数组则是原装。
以eclipse为例看参数设置:
3. 多个实现类的执行顺序
两种方法
- 使用@Order(value=整数值)
- 实现Ordered接口,在方法里return 一个顺序值