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服务器的?
318 0
《SpringBoot启动流程七》:源码分析SpringBoot如何内嵌并启动Tomcat服务器的?
|
Java Spring 容器
《SpringBoot启动流程六》:SpringBoot自动装配时做条件装配的原理(万字图文源码分析)(含@ConditionalOnClass原理)
《SpringBoot启动流程六》:SpringBoot自动装配时做条件装配的原理(万字图文源码分析)(含@ConditionalOnClass原理)
344 0
《SpringBoot启动流程六》:SpringBoot自动装配时做条件装配的原理(万字图文源码分析)(含@ConditionalOnClass原理)
|
Java Spring
《SpringBoot启动流程五》:你真的知道SpringBoot自动装配原理吗(两万字图文源码分析)
《SpringBoot启动流程五》:你真的知道SpringBoot自动装配原理吗(两万字图文源码分析)
160 0
《SpringBoot启动流程五》:你真的知道SpringBoot自动装配原理吗(两万字图文源码分析)
|
Java 应用服务中间件 Spring
《SpringBoot启动流程四》:图文带你debug源码分析SpringApplication运行阶段和运行后阶段
《SpringBoot启动流程四》:图文带你debug源码分析SpringApplication运行阶段和运行后阶段
194 0
《SpringBoot启动流程四》:图文带你debug源码分析SpringApplication运行阶段和运行后阶段
|
监控 安全 Java
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
257 0
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
|
存储 缓存 前端开发
《SpringBoot启动流程二》:七千字源码分析SpringApplication构造阶段
《SpringBoot启动流程二》:七千字源码分析SpringApplication构造阶段
121 0
《SpringBoot启动流程二》:七千字源码分析SpringApplication构造阶段
|
Java 程序员 开发者
自定义spring boot starter三部曲之三:源码分析spring.factories加载过程
分析Spring和Spring boot源码,了解spring.factories自动加载原理
273 0
自定义spring boot starter三部曲之三:源码分析spring.factories加载过程
|
安全 Java
Springboot 别名管理源码分析
# 别名的注册 SimpleAliasRegistry维护了一个映射别名到真实名称的aliasMap这里使用的是线程安全的ConcurrentHashMap,即在多线程的情况下也可以对同一个bean安全地进行别名的增删改查。同时也说明了**一个别名只能对应一个真名,而一个真名没有对应多个别名**。由于SimpleAliasRegistry是对项目全局别名的管理,**任意别名都必须是全局唯一的**。
170 0
|
NoSQL Java Redis
SpringBoot自动化配置源码分析
SpringBoot 的自动化配置让我们的开发彻底远离了 Spring 繁琐的各种配置,让我们专注于开发,但是SpringBoot 的自动化配置是怎么实现的呢?下面为你揭开 SpringBoot 自动化配置的神秘面纱。
98 0
SpringBoot自动化配置源码分析
|
设计模式 Java 网络架构
SpringBoot请求映射源码分析(没看过源码的小白也能懂,比针尖还细)
SpringBoot请求映射源码分析(没看过源码的小白也能懂,比针尖还细)
238 0
SpringBoot请求映射源码分析(没看过源码的小白也能懂,比针尖还细)