CommandLineRunner与ApplicationRunner接口的使用及源码解析

栏目: Java · 发布时间: 7年前

内容简介:我们在使用SpringBoot搭建项目的时候,如果希望在项目启动完成之前,能够初始化一些操作,针对这种需求,可以考虑实现如下两个接口(任一个都可以)CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调(类似开机自启动)。接口被用作将其加入spring容器中时执行其run方法。多个CommandLineRunner可以被同时执行在同一个spring上下文中并且执行顺序是以order注解的参数顺序一致。

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

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

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

CommandLineRunner接口

CommandLineRunner与ApplicationRunner接口的使用及源码解析
官方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{
    @Override
    public 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{
    @Override
    public 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"));
    }
}
复制代码

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

CommandLineRunner与ApplicationRunner接口的使用及源码解析

打印结果

CommandLineRunner与ApplicationRunner接口的使用及源码解析

ApplicationRunner接口

CommandLineRunner与ApplicationRunner接口的使用及源码解析
发现二者的官方javadoc一样,区别在于接收的参数不一样。 CommandLineRunner 的参数是最原始的参数,没有做任何处理。 ApplicationRunner 的参数是 ApplicationArguments

,是对原始参数做了进一步的封装。

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

CommandLineRunner与ApplicationRunner接口的使用及源码解析
可以接收 --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{
    @Override
    public 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接口的使用及源码解析

打印结果

CommandLineRunner与ApplicationRunner接口的使用及源码解析

总结

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

扩展阅读

CommandLineRunner、ApplicationRunner执行流程源码分析

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

SpringApplication.run(args)

CommandLineRunner与ApplicationRunner接口的使用及源码解析
CommandLineRunner与ApplicationRunner接口的使用及源码解析

this.afterRefresh(context, applicationArguments)方法

CommandLineRunner与ApplicationRunner接口的使用及源码解析

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

CommandLineRunner与ApplicationRunner接口的使用及源码解析
CommandLineRunner与ApplicationRunner接口的使用及源码解析
CommandLineRunner与ApplicationRunner接口的使用及源码解析
总结:通过以上分析可知,实现这两个接口的类,在 ApplicationContext.run()

方法里被执行

CommandLineRunner与ApplicationRunner接口的使用及源码解析

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Probability and Computing

Probability and Computing

Michael Mitzenmacher、Eli Upfal / Cambridge University Press / 2005-01-31 / USD 66.00

Assuming only an elementary background in discrete mathematics, this textbook is an excellent introduction to the probabilistic techniques and paradigms used in the development of probabilistic algori......一起来看看 《Probability and Computing》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具