Spring Boot - ApplicationRunner && CommandLineRunner扩展接口
Posted 小小工匠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot - ApplicationRunner && CommandLineRunner扩展接口相关的知识,希望对你有一定的参考价值。
文章目录
Pre
org.springframework.boot.CommandLineRunner
/**
* Interface used to indicate that a bean should <em>run</em> when it is contained within
* a @link SpringApplication. Multiple @link CommandLineRunner beans can be defined
* within the same application context and can be ordered using the @link Ordered
* interface or @link Order @Order annotation.
* <p>
* If you need access to @link ApplicationArguments instead of the raw String array
* consider using @link ApplicationRunner.
*
* @author Dave Syer
* @since 1.0.0
* @see ApplicationRunner
*/
@FunctionalInterface
public interface CommandLineRunner
/**
* Callback used to run the bean.
* @param args incoming main method arguments
* @throws Exception on error
*/
void run(String... args) throws Exception;
接口也只有一个方法:run(String... args)
如果有多个CommandLineRunner
,可以利用@Order来进行排序, 按照@Order
中的value值从小到大依次执行。
使用场景
-
触发时机为整个项目启动完毕后(执行时机为容器启动完成的时候),自动执行。
-
扩展此接口,进行启动项目之后一些业务的预处理。
源码解析
/**
* Run the Spring application, creating and refreshing a new
* @link ApplicationContext.
* @param args the application arguments (usually passed from a Java main method)
* @return a running @link ApplicationContext
*/
public ConfigurableApplicationContext run(String... args)
// 创建并启动计时监控类
StopWatch stopWatch = new StopWatch();
stopWatch.start();
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
// 创建所有 Spring 运行监听器并发布应用启动事件
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try
// 处理 args 参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 准备环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
// 创建应用上下文
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// 准备应用上下文
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新应用上下文
refreshContext(context);
// 应用上下文刷新之后的事件的处理
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo)
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
// 发布应用上下文启动完成事件
listeners.started(context);]
// 执行所有 Runner 运行器
callRunners(context, applicationArguments);
catch (Throwable ex)
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
try
// 发布应用上下文就绪事件
listeners.running(context);
catch (Throwable ex)
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
return context;
继续 this.callRunners(context, applicationArguments);
核心方法 callRunners
private void callRunners(ApplicationContext context, ApplicationArguments args)
//将实现ApplicationRunner和CommandLineRunner接口的类,存储到集合中
List<Object> runners = new ArrayList<>();
// 从Spring容器中查找类型为ApplicationRunner的Bean
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
// 从Spring容器中查找类型为CommandLineRunner的Bean
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
//按照加载先后顺序排序
AnnotationAwareOrderComparator.sort(runners);
//调用执行
for (Object runner : new LinkedHashSet<>(runners))
//如果是ApplicationRunner的实例
if (runner instanceof ApplicationRunner)
callRunner((ApplicationRunner) runner, args);
//如果是CommandLineRunner的实例
if (runner instanceof CommandLineRunner)
callRunner((CommandLineRunner) runner, args);
private void callRunner(ApplicationRunner runner, ApplicationArguments args)
try
//调用各个实现类中的逻辑实现
(runner).run(args);
catch (Exception ex)
throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
OK, CLEAR
扩展示例
ApplicationRunner
package com.artisan.bootspringextend.testextends;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
/**
* @author 小工匠
* @version 1.0
* @description: TODO
* @date 2022/12/7 11:49
* @mark: show me the code , change the world
*/
@Slf4j
@Configuration
public class ExtendApplicationRunner implements ApplicationRunner
@Override
public void run(ApplicationArguments args) throws Exception
log.info(">>>>>>>ExtendApplicationRunner#run called ",args);
CommandLineRunner
package com.artisan.bootspringextend.testextends;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
/**
* @author 小工匠
* @version 1.0
* @description: TODO
* @date 2022/12/7 9:01
* @mark: show me the code , change the world
*/
@Slf4j
@Configuration
public class ExtendCommandLineRunner implements CommandLineRunner
@Override
public void run(String... args) throws Exception
log.info(">>>>>>>ExtendCommandLineRunner#run called ",args);
以上是关于Spring Boot - ApplicationRunner && CommandLineRunner扩展接口的主要内容,如果未能解决你的问题,请参考以下文章
如何 JUnit 测试 Spring-Boot 的 Application.java
Spring boot jsp 和 application.yml
Spring Boot 配置文件application.properties
Spring Boot Common application properties(转载)
使用 spring boot 和 spring-boot-maven-plugin 生成战争时排除 application.properties