Spring扩展接口-CommandLineRunner、ApplicationRunner
简介
Spring启动时,容器刷新完成之后,提供了扩展接口CommandLineRunner或者ApplicationRunner, 执行最后的逻辑。
public interface ApplicationRunner {
void run(ApplicationArguments args) throws Exception;
}
public interface CommandLineRunner {
void run(String... args) throws Exception;
}
先来看接口官方定义。 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. bean加入Spring上下文容器时,应该运行的接口。多个CommandLineRunner可以在同一个spring上下文中同时执行,并且可以使用order注解调整执行顺序。 If you need access to ApplicationArguments instead of the raw String array consider using ApplicationRunner. 如果你需要访问ApplicationArguments去替换掉字符串数组,可以考虑使用ApplicationRunner类。
CommandLineRunner和ApplicationRunner的作用是相同的。不同之处在于CommandLineRunner接口的run()方法接收String数组作为参数,即是最原始的参数,没有做任何处理;而ApplicationRunner接口的run()方法接收ApplicationArguments对象作为参数,是对原始参数做了进一步的封装。
在开发过程中会有这样的场景:需要在容器启动的时候执行一些内容,比如:读取配置文件信息,数据库连接,删除临时文件,清除缓存信息,在Spring框架下是通过ApplicationListener监听器来实现的。在Spring Boot中给我们提供了两个接口CommandLineRunner和ApplicationRunner,来帮助我们实现这样的需求。
在所有的CommandLineRunner和ApplicationRunner回调之前,下面的步骤已经确保执行完毕: (1)Environment内置变量的创建和属性填充已经完成。 (2)Banner已经打印完毕。 (3)ApplicationContext和BeanFactory创建完成,并且完成了上下文刷新(refreshContext),意味着所有单例的Bean完成了初始化以及属性装配。 (4)Servlet容器启动成功,如内置的Tomcat、Jetty容器已经正常启动,可以正常接收请求和处理。 (5)启动信息完成打印,一般会看到日志输出类似Started ***Application in *** seconds (JVM running for ***)。 应用程序启动后,需要执行特定的代码,比如加载缓存数据、打印自定义启动信息等。Spring Boot 为我们提供了ApplicationRunner、CommandLineRunner两个接口来实现上面的需求。
使用场景上,应用服务启动时,加载一些数据和执行一些应用的初始化动作。举例说明: (1)删除临时文件。 (2)缓存预热:项目启动时热加载数据库数据至缓存。 (3)清除缓存信息。 (4)读取配置文件信息。 (5)打印日志用于标识服务启动成功或者标识某些属性加载成功。 (6)设置属性值或者启动组件,例如开启某些组件的开关、一些应用级别缓存的加载、启动定时任务等等。 (7)需要使用main方法的入参。
应用实例
CommandLineRunner简易demo
@Order(1)
@Component
public class PrintArgsService implements CommandLineRunner{
@Override
public void run(String... args) throws Exception {
System.out.println("=====应用已经成功启动====="+ Arrays.asList(args));
}
}
@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());
));
}
}
启动时添加入参:aaa,bb
ApplicationRunner简易demo
@Order(1)
@Component
public class PrintArgsServiceV2 implements ApplicationRunner{
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("===MyApplicationRunner==="+ Arrays.asList(args.getSourceArgs()));
System.out.println("===getOptionNames========"+args.getOptionNames());
}
}
@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());
));
}
}
启动时添加入参:--foo=aaa --developer.name=run.test
更多信息请移步Spring专栏:www.yuque.com/mrhuang-ire…
参考: [1].www.jianshu.com/p/5d4ffe267…
本文来自博客园,作者:扎Zn了老Fe,转载请注明原文链接:https://www.cnblogs.com/itThinking/p/17771110.html