前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot - ApplicationRunner && CommandLineRunner扩展接口

Spring Boot - ApplicationRunner && CommandLineRunner扩展接口

作者头像
小小工匠
发布2022-12-09 14:14:19
6810
发布2022-12-09 14:14:19
举报
文章被收录于专栏:小工匠聊架构

文章目录

在这里插入图片描述
在这里插入图片描述

Pre

Spring Boot - 扩展接口一览

在这里插入图片描述
在这里插入图片描述

org.springframework.boot.CommandLineRunner

代码语言:javascript
复制
/**
 * 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值从小到大依次执行。


使用场景

  • 触发时机为整个项目启动完毕后(执行时机为容器启动完成的时候),自动执行。
  • 扩展此接口,进行启动项目之后一些业务的预处理。

源码解析

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
	/**
	 * 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

代码语言:javascript
复制
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);
			}
		}
	}
代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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);
    }
}
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • Pre
  • org.springframework.boot.CommandLineRunner
  • 使用场景
  • 源码解析
  • 扩展示例
    • ApplicationRunner
      • CommandLineRunner
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档