我是靠谱客的博主 欢呼店员,最近开发中收集的这篇文章主要介绍CommandLineRunner与ApplicationRunner接口的使用及源码解析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

引言

我们在使用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{
@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"));
}
}
复制代码

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

打印结果

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{
@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接口均可实现应用启动初始化某些功能的需求,如果希望对参数有更多的操作,则可以选择实现ApplicationRunner接口。

扩展阅读

CommandLineRunner、ApplicationRunner执行流程源码分析

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

SpringApplication.run(args)

this.afterRefresh(context, applicationArguments)方法

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

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

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

最后

以上就是欢呼店员为你收集整理的CommandLineRunner与ApplicationRunner接口的使用及源码解析的全部内容,希望文章能够帮你解决CommandLineRunner与ApplicationRunner接口的使用及源码解析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部