引言

我们在使用SpringBoot搭建项目的时候,如果希望在项目启动完成之前,能够初始化一些操作,针对这种需求,可以考虑实现如下两个接口(任一个都可以)

org.springframework.boot.CommandLineRunner
org.springframework.boot.ApplicationRunner
复制代码

CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调(类似开机自启动)。

CommandLineRunner接口

官方doc: 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.

接口被用作将其加入spring容器中时执行其run方法。多个CommandLineRunner可以被同时执行在同一个spring上下文中并且执行顺序是以order注解的参数顺序一致。

If you need access to ApplicationArguments instead of the raw String array consider using ApplicationRunner.

如果你需要访问ApplicationArguments去替换掉字符串数组,可以考虑使用ApplicationRunner类。

实例demo

定义一个ServerStartedReport实现CommandLineRunner,并纳入到srping容器中进行处理

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;@Order(2)
@Component
public class ServerStartedReport implements CommandLineRunner{@Overridepublic void run(String... args) throws Exception {System.out.println("===========ServerStartedReport启动====="+ LocalDateTime.now());}
}
复制代码

定义一个ServerSuccessReport实现CommandLineRunner,并纳入到spring容器处理

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;@Order(1)
@Component
public class ServerSuccessReport implements CommandLineRunner{@Overridepublic void run(String... args) throws Exception {System.out.println("=====应用已经成功启动====="+ Arrays.asList(args));}
}
复制代码

启动类测试,也可以直接在spring容器访问该值,

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@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());System.out.println("values===="+applicationArguments.getOptionValues("developer.name"));}
}
复制代码

配置参数,然后执行启动类

打印结果

ApplicationRunner接口

发现二者的官方javadoc一样,区别在于接收的参数不一样。CommandLineRunner的参数是最原始的参数,没有做任何处理。ApplicationRunner的参数是ApplicationArguments,是对原始参数做了进一步的封装。

ApplicationArguments是对参数(main方法)做了进一步的处理,可以解析--name=value的,我们就可以通过name来获取value(而CommandLineRunner只是获取--name=value)

可以接收--foo=bar这样的参数。

  • getOptionNames()方法可以得到foo这样的key的集合。
  • getOptionValues(String name)方法可以得到bar这样的集合的value。

实例demo

定义MyApplicationRunner类继承ApplicationRunner接口,

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;@Component
public class MyApplicationRunner implements ApplicationRunner{@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("===MyApplicationRunner==="+ Arrays.asList(args.getSourceArgs()));System.out.println("===getOptionNames========"+args.getOptionNames());System.out.println("===getOptionValues======="+args.getOptionValues("foo"));System.out.println("==getOptionValues========"+args.getOptionValues("developer.name"));}
}
复制代码

启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class,args);}
}
复制代码

配置参数启动

打印结果

总结

用户使用CommandLineRunner或者ApplicationRunner接口均可实现应用启动初始化某些功能的需求,如果希望对参数有更多的操作,则可以选择实现ApplicationRunner接口。

扩展阅读

CommandLineRunner、ApplicationRunner执行流程源码分析

用户只要实现这两个接口,其中的run方法就会在项目启动时候被自动调用,那么究竟是在什么时候调用的呢?下面可以看一下Application的启动流程

SpringApplication.run(args)

this.afterRefresh(context, applicationArguments)方法

跟踪context.getBeansOfType()方法,具体实现在类DefaultListableBeanFactory中

总结:通过以上分析可知,实现这两个接口的类,在ApplicationContext.run()方法里被执行

转载于:https://juejin.im/post/5ce3508af265da1bb80c0195

CommandLineRunner与ApplicationRunner接口的使用及源码解析相关推荐

  1. webserver接口_SpringBoot内置源码解析WebServer初始化过程

    WebServer 初始化过程 在上一节中 Spring Boot 初始化了 WebServer 对应的工厂类.同时,我们也知道对应 Web容器的WebServer实现类有:TomcatWebServ ...

  2. 创建线程的第三种方式:实现Callable接口(含部分源码解析)

    创建线程的第三种方式--实现Callable接口 package com.lqy.Multithreading; import java.util.concurrent.Callable; impor ...

  3. loraserver 源码解析 (六) lora-app-server

    目录 下载源码 升级 npm 安装一些必要的依赖库 pq_trgm extension run 调用 handleDataDownPayloads 开启一个Goroutine  G1 run再调用 s ...

  4. Flume-ng源码解析之Channel组件

    如果还没看过Flume-ng源码解析之启动流程,可以点击Flume-ng源码解析之启动流程 查看 1 接口介绍 组件的分析顺序是按照上一篇中启动顺序来分析的,首先是Channel,然后是Sink,最后 ...

  5. 使用CommandLineRunner或ApplicationRunner接口创建bean

    在spring boot应用中,我们可以在程序启动之前执行任何任务.为了达到这个目的,我们需要使用CommandLineRunner或ApplicationRunner接口创建bean,spring ...

  6. CommandLineRunner、ApplicationRunner 接口

    如果我们想在项目启动后做一些事情(如加载定时任务,初始化工作),可以使用spring提供的CommandLineRunner.ApplicationRunner 接口,在容器启动成功后的最后一步回调( ...

  7. java迭代器创建后mutx锁,java集合【5】—— Collections接口源码解析

    一.Collections接口是做什么的? 用官网文档的介绍:The polymorphic algorithms described here are pieces of reusable func ...

  8. Spring源码解析 - AbstractBeanFactory 实现接口与父类分析

    2019独角兽企业重金招聘Python工程师标准>>> 我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegi ...

  9. 04【Verilog实战】SPI协议底层硬件接口设计(附源码RTL/TB)

    脚  本:makefile 工  具:vcs 和 verdi 写在前面 这个专栏的内容记录的是个人学习过程,博文中贴出来的代码是调试前的代码,方便bug重现. 调试后的程序提供下载,[下载地址] 发现 ...

最新文章

  1. Spring Boot 前后端配合及接口化测试学习记录[3]
  2. 装饰者模式 php,PHP设计模式之装饰器模式
  3. GPT「高仿」问世:GPT-Neo,最大可达GPT-3大小,已开源 | AI日报
  4. YYAnimatedImageView--gif在ios14之后只能播放一次
  5. dell 如何给raid分区_什么是RAID技术?
  6. excel转latex,markdown,html表格的神仙网站!科研必备!
  7. 浅谈python的对象的三大特性之封装
  8. 切图网——好的网站结构有利于seo
  9. 什么时候需要好教材和好教材是怎样的
  10. eclipseini设置使用的jdk_系统安全篇(四)-如何升级JDK版本?
  11. 大家都为什么考博?采访了12名考生,发现最主要原因竟是这个
  12. 7 学大厂,拓展基础组件封装思路 BAT?TMD
  13. 使用万能框架HttpHelper抓取安卓APP数据
  14. 要想下班早,微服务架构少不了
  15. Mobaxterm中使用git log报错/bin/busybox.exe less -R no such file or directory
  16. 笨办法学 Python · 续 练习 27:`tr`
  17. SOLR对多个(关联)表创建索引
  18. oracle12能卸干净吗,Oracle卸载干净方法
  19. 中国志愿者服务器注册,如何注册成为志愿者?中国志愿服务网注册流程
  20. udacity 学java_刷完udacity的JavaScript,我想说……

热门文章

  1. 【性能优化】 之 几种常见的等待事件的演示示例
  2. sqlserver游标概念与实例
  3. Position(Static, Absolute, Relative, Fixed)
  4. 算法测试—机器学习算法评价指标
  5. Redis—主从复制
  6. v1.0.2-2017.04.26
  7. 拓扑排序基础题——排序
  8. python模块中的__all__属性
  9. ckeditor_学习(2) 功能概览
  10. 关于字符编码,你所需要知道的(ASCII,Unicode,Utf-8,GB2312…)