内容简介:我们在使用SpringBoot搭建项目的时候,如果希望在项目启动完成之前,能够初始化一些操作,针对这种需求,可以考虑实现如下两个接口(任一个都可以)CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调(类似开机自启动)。接口被用作将其加入spring容器中时执行其run方法。多个CommandLineRunner可以被同时执行在同一个spring上下文中并且执行顺序是以order注解的参数顺序一致。
我们在使用SpringBoot搭建项目的时候,如果希望在项目启动完成之前,能够初始化一些操作,针对这种需求,可以考虑实现如下两个接口(任一个都可以)
org.springframework.boot.CommandLineRunner org.springframework.boot.ApplicationRunner 复制代码
CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调(类似开机自启动)。
CommandLineRunner接口
官方doc:Interface used to indicate that a bean should run when it is contained within a SpringApplication. Multiple CommandLineRunner beans can be defined within the same application context and can be ordered using the Ordered interface or Order @Order annotation.
接口被用作将其加入spring容器中时执行其run方法。多个CommandLineRunner可以被同时执行在同一个spring上下文中并且执行顺序是以order注解的参数顺序一致。
If you need access to ApplicationArguments instead of the raw String array consider using ApplicationRunner.
如果你需要访问ApplicationArguments去替换掉字符串数组,可以考虑使用ApplicationRunner类。
实例demo
定义一个ServerStartedReport实现CommandLineRunner,并纳入到srping容器中进行处理
import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.time.LocalDateTime; @Order(2) @Component public class ServerStartedReport implements CommandLineRunner{ @Override public void run(String... args) throws Exception { System.out.println("===========ServerStartedReport启动====="+ LocalDateTime.now()); } } 复制代码
定义一个ServerSuccessReport实现CommandLineRunner,并纳入到spring容器处理
import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.Arrays; @Order(1) @Component public class ServerSuccessReport implements CommandLineRunner{ @Override public void run(String... args) throws Exception { System.out.println("=====应用已经成功启动====="+ Arrays.asList(args)); } } 复制代码
启动类测试,也可以直接在spring容器访问该值,
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { ConfigurableApplicationContext context =SpringApplication.run(Application.class,args); ApplicationArguments applicationArguments = context.getBean(ApplicationArguments.class); System.out.println("============"); System.out.println("name="+applicationArguments.getOptionNames()); System.out.println("values===="+applicationArguments.getOptionValues("developer.name")); } } 复制代码
配置参数,然后执行启动类
打印结果
ApplicationRunner接口
发现二者的官方javadoc一样,区别在于接收的参数不一样。CommandLineRunner
的参数是最原始的参数,没有做任何处理。
ApplicationRunner
的参数是
ApplicationArguments
,是对原始参数做了进一步的封装。
ApplicationArguments
是对参数(main方法)做了进一步的处理,可以解析--name=value的,我们就可以通过name来获取value(而CommandLineRunner只是获取--name=value)
--foo=bar
这样的参数。
- getOptionNames()方法可以得到foo这样的key的集合。
- getOptionValues(String name)方法可以得到bar这样的集合的value。
实例demo
定义MyApplicationRunner类继承ApplicationRunner接口,
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import java.util.Arrays; @Component public class MyApplicationRunner implements ApplicationRunner{ @Override public void run(ApplicationArguments args) throws Exception { System.out.println("===MyApplicationRunner==="+ Arrays.asList(args.getSourceArgs())); System.out.println("===getOptionNames========"+args.getOptionNames()); System.out.println("===getOptionValues======="+args.getOptionValues("foo")); System.out.println("==getOptionValues========"+args.getOptionValues("developer.name")); } } 复制代码
启动类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } } 复制代码
配置参数启动
打印结果
总结
用户使用CommandLineRunner或者ApplicationRunner接口均可实现应用启动初始化某些功能的需求,如果希望对参数有更多的操作,则可以选择实现ApplicationRunner接口。
扩展阅读
CommandLineRunner、ApplicationRunner执行流程源码分析
用户只要实现这两个接口,其中的run方法就会在项目启动时候被自动调用,那么究竟是在什么时候调用的呢?下面可以看一下Application的启动流程
SpringApplication.run(args)
this.afterRefresh(context, applicationArguments)方法
跟踪context.getBeansOfType()方法,具体实现在类DefaultListableBeanFactory中
总结:通过以上分析可知,实现这两个接口的类,在ApplicationContext.run()
方法里被执行
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- ReactNative源码解析-初识源码
- Spring源码系列:BeanDefinition源码解析
- Spring源码分析:AOP源码解析(下篇)
- Spring源码分析:AOP源码解析(上篇)
- 注册中心 Eureka 源码解析 —— EndPoint 与 解析器
- 新一代Json解析库Moshi源码解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Non-Obvious
Rohit Bhargava / Ideapress Publishing / 2015-3-29 / USD 24.95
What do Disney, Bollywood, and The Batkid teach us about how to create celebrity experiences for our audiences? How can a vending-machine inspire world peace? Can being imperfect make your business mo......一起来看看 《Non-Obvious》 这本书的介绍吧!