SpringBoot源码分析之CommandLineRunner、ApplicationRunner

简介: 我们在之前的文章中简单的说过SpringBoot的CommandLineRunner和ApplicationRunner这两个接口 SpringBoot之CommandLineRunner接口和ApplicationRunner接口,这篇文章中我们从源码上简单的分析一下这两个 接口。

我们在之前的文章中简单的说过SpringBoot的CommandLineRunner和ApplicationRunner这两个接口
SpringBoot之CommandLineRunner接口和ApplicationRunner接口,这篇文章中我们从源码上简单的分析一下这两个
接口。在org.springframework.boot.SpringApplication#run()这个方法中有这样一段代码:

afterRefresh(context, applicationArguments);

方法内容如下:

    protected void afterRefresh(ConfigurableApplicationContext context,
            ApplicationArguments args) {
        callRunners(context, args);
    }

SpringBoot的注释中说,在上下文刷新完之后调用这个方法。在调用这个方法的时候Spring容器已经启动完
成了。这里的context的真正对象是:AnnotationConfigEmbeddedWebApplicationContext,这个类贯
穿着SpringBoot的整个启动过程。我们看一下callRunners这个方法的内容:

    private void callRunners(ApplicationContext context, ApplicationArguments args) {
        List<Object> runners = new ArrayList<Object>();
        //从Spring容器中查找类型为ApplicationRunner的Bean
        runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
        //从Spring容器中查找类型为CommandLineRunner的Bean
        runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
        //将上一步得到的Bean进行排序
        AnnotationAwareOrderComparator.sort(runners);
        for (Object runner : new LinkedHashSet<Object>(runners)) {
            //如果是ApplicationRunner的实例
            if (runner instanceof ApplicationRunner) {
                callRunner((ApplicationRunner) runner, args);
            }
            //如果是CommandLineRunner的实例
            if (runner instanceof CommandLineRunner) {
                callRunner((CommandLineRunner) runner, args);
            }
        }
    }

callRunner方法的内容就很简单了直接调用run方法。

    private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
        try {
            (runner).run(args);
        }
        catch (Exception ex) {
            throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
        }
    }

ApplicationRunner和CommandLineRunner的区别就是run方法参数不同,ApplicationRunner中run方法
的参数是ApplicationArguments,CommandLineRunner中run方法的参数是String类型的可变参数。。

相关文章
|
前端开发 Java 应用服务中间件
《SpringBoot启动流程七》:源码分析SpringBoot如何内嵌并启动Tomcat服务器的?
《SpringBoot启动流程七》:源码分析SpringBoot如何内嵌并启动Tomcat服务器的?
464 0
《SpringBoot启动流程七》:源码分析SpringBoot如何内嵌并启动Tomcat服务器的?
|
Java Spring 容器
《SpringBoot启动流程六》:SpringBoot自动装配时做条件装配的原理(万字图文源码分析)(含@ConditionalOnClass原理)
《SpringBoot启动流程六》:SpringBoot自动装配时做条件装配的原理(万字图文源码分析)(含@ConditionalOnClass原理)
433 0
《SpringBoot启动流程六》:SpringBoot自动装配时做条件装配的原理(万字图文源码分析)(含@ConditionalOnClass原理)
|
Java Spring
《SpringBoot启动流程五》:你真的知道SpringBoot自动装配原理吗(两万字图文源码分析)
《SpringBoot启动流程五》:你真的知道SpringBoot自动装配原理吗(两万字图文源码分析)
209 0
《SpringBoot启动流程五》:你真的知道SpringBoot自动装配原理吗(两万字图文源码分析)
|
Java 应用服务中间件 Spring
《SpringBoot启动流程四》:图文带你debug源码分析SpringApplication运行阶段和运行后阶段
《SpringBoot启动流程四》:图文带你debug源码分析SpringApplication运行阶段和运行后阶段
271 0
《SpringBoot启动流程四》:图文带你debug源码分析SpringApplication运行阶段和运行后阶段
|
监控 安全 Java
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
344 0
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
|
存储 缓存 前端开发
《SpringBoot启动流程二》:七千字源码分析SpringApplication构造阶段
《SpringBoot启动流程二》:七千字源码分析SpringApplication构造阶段
178 0
《SpringBoot启动流程二》:七千字源码分析SpringApplication构造阶段
|
Java 程序员 开发者
自定义spring boot starter三部曲之三:源码分析spring.factories加载过程
分析Spring和Spring boot源码,了解spring.factories自动加载原理
343 0
自定义spring boot starter三部曲之三:源码分析spring.factories加载过程
|
NoSQL Java Redis
SpringBoot自动化配置源码分析
SpringBoot 的自动化配置让我们的开发彻底远离了 Spring 繁琐的各种配置,让我们专注于开发,但是SpringBoot 的自动化配置是怎么实现的呢?下面为你揭开 SpringBoot 自动化配置的神秘面纱。
129 0
SpringBoot自动化配置源码分析
|
设计模式 Java 网络架构
SpringBoot请求映射源码分析(没看过源码的小白也能懂,比针尖还细)
SpringBoot请求映射源码分析(没看过源码的小白也能懂,比针尖还细)
318 0
SpringBoot请求映射源码分析(没看过源码的小白也能懂,比针尖还细)
|
XML Java 数据格式
SpringBoot源码分析系列之五:再探自动装配原理
我们从程序运行的角度把自动配置的主要的源码进行了分析,过滤了一些步骤,主要是调用层级太多容易让人抓不住重点,这边也是给大家看源码的一点小技巧就是抓大放小,抓住主要流程,忽略掉小的细节部分,否则我们就会陷入到源码的汪洋之中无法自拔。
SpringBoot源码分析系列之五:再探自动装配原理