SpringBoot2.x基础篇:使用CommandLineRunner或ApplicationRunner
如果你想要使用SpringBoot构建的项目在启动后运行一些特定的代码,那么CommandLineRunner、ApplicationRunner都是很好的选择。
推荐阅读
使用方式
我们以CommandLineRunner创建了一个简单的例子,如下所示:
1 | /** |
CommandLineRunner接口的定义很简单,只提供了一个名为#run()的方法,我们只需要实现该方法做一些自定义的业务逻辑即可,ApplicationRunner接口的使用方式也是一样的。
两者的区别?
从源码上分析,CommandLineRunner与ApplicationRunner两者之间只有#run()方法的参数不一样而已。
CommandLineRunner:
1 |
|
ApplicationRunner:
1 |
|
CommandLineRunner#run()方法的参数是启动SpringBoot应用程序main方法的参数列表,而ApplicationRunner#run()方法的参数则是ApplicationArguments对象。
在之前的文章中也提到过ApplicatgionArguments对象,并使用它获取外部的配置参数,查看:应用程序在启动时访问启动项参数。
建议:如果你在项目启动时需要获取类似 “–xxx” 的启动参数值建议使用
ApplicationRunner
什么时候会被调用?
我们已经了解CommandLineRunner与ApplicationRunner两个接口的使用以及区别,是不是很想知道SpringBoot在启动时在什么时候调用它们的呢?
我们大家都知道SpringBoot应用程序的启动主要归功于SpringApplication这个类,我们在创建项目时在启动类内会调用SpringApplication#run()方法,如下所示:
1 | public static void main(String[] args) { |
那我们来查看下SpringApplication类#run()方法的源码,根据查看方法之间的相互调用,最终我们会定位到org.springframework.boot.SpringApplication#run(java.lang.String...)这个方法,阅读该方法时发现有关调用Runner的定义,如下所示:
1 | // 省略部分源码 |
#callRunnners()方法的调用确实是在应用程序启动完成后,而且把ApplicationContext与ApplicationArguments对象都作为参数进行了传递,那么我们来看看这个方法究竟干了些什么事情?
SpringApplication#callRunners:
1 | private void callRunners(ApplicationContext context, ApplicationArguments args) { |
我想大家看到这里就应该明白了,这个方法就是在执行CommandLineRunner以及ApplicationRunner实现类实例的#run()方法,首先会从ApplicationContext中获取CommandLineRunner、ApplicationRunner接口实现类的实例,然后根据不同类型的Runner实例去调用了callRunner方法。
SpringApplication#callRunner:
1 |
|
设置执行顺序
那如果我们创建了多个CommandLineRunner、ApplicationRunner实现类,还想要实现类在执行的时候有一定的先后顺序,那你不妨试下org.springframework.core.annotation.Order这个注解或者实现org.springframework.core.Ordered接口。
CommandLineRunnerExample:
1 | /** |
接口与注解的方式选择其中一种就可以了。
SpringBoot2.x基础篇:使用CommandLineRunner或ApplicationRunner
https://blog.minbox.org/spring-boot-basic-use-commandlinerunner-or-applicationrunner.html

OAuth vs SAML vs OpenID
