Springboot ApplicationRunner的使用解读

 更新时间:2023年05月16日 09:38:30   作者:澄风  
这篇文章主要介绍了Springboot ApplicationRunner的使用解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Springboot ApplicationRunner使用

ApplicationRunner介绍

ApplicationRunner是在应用容器启动之后会回调到,在ApplicationStartedListener调用之后被调用。

如果说ApplicationListener中有阻塞,那么ApplicationRunner也都不会被调用。

@Component
public class ApplicationRunnerTest implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(args);
    }
}

我们可以在applicationRunner中做一些异步启动的操作,比如实例化Kafka客户端,异步加载缓存等等在服务启动之后不立马提供服务的操作。

通过分析源码可以知道runner实在容器加载完成以及ApplicationStartedListener调用之后进行回调的。

ApplicationRunner为什么不被调用

问题描述

在项目中写了一个ApplicationRunner 来启动消费队列线程,结果启动的时候applicationRunner的run方法死活不被调用。

问题分析

通过debug发现,在springboot初始化完环境refresh context之后就会调用started listener然后调用application runner,如果started listner 存在阻塞的话就会导致后续的application runner 不被运行。

而我在另一个组件中使用ApplicationListener<ApplicationStartedEvent> 去启动了netty server,启动netty server会导致当前线程阻塞以至于application runner 不被调用。

问题解决

在listener和Runner当中尽量启用线程来跑阻塞而不是直接去跑阻塞任务。

ApplicationRunner的作用是什么?

有时针对一些特殊的业务场景,需要在系统启动时执行某些任务,如:配置文件的加载、数据库的初始化等等操作。

SpringBoot 提供了两种解决方案:

  • 一种是使用CommandLineRunner
  • 另一种是使用 ApplicationRunner

基本原理

项目在启动时会遍历所有的 ApplicationRunner 的实现类并调用其中的 run 方法,如果在系统中有多个 ApplicationRunner的实现类,可以使用 @Order 注解对这些实现类的调用顺序进行排序(数字越小越先执行);run方法的参数是系统启动时传入的参数,即入口类中main方法的参数(在调用SpringApplication.run方法时传入到 SpringBoot项目的上下文环境中)。

如何使用

@Component
@Slf4j
@Order(1)
public class MyApplicationRunner implements ApplicationRunner {
    // ApplicationArguments, 需要区分选项参数和非选项参数;
    // 选项参数, 通过ApplicationArguments的getOptionNames()方法获取所有选项名称即参数的KEY, 然后通过 getOptionValues()方法根据参数KEY, 获取实际值(它会返回一个列表字符串), 一般为: --user-name=ROCKY --age=30
    // 非选项参数, 通过ApplicationArguments的getNonOptionArgs()方法获取一个参数值数组;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        // TO DO SOMETHING...
    }
}

ApplicationRunner和CommandLineRunner的区别

@Component
@Slf4j
@Order(1)
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        // TO DO SOMETHING...
    }
} 

ApplicationRunner与CommandLineRunner的主要区别体现在run方法的参数上,CommandLineRunner中的run方法的参数是参数数组;ApplicationRunner中的run方法的参数是ApplicationArguments对象。

执行顺序

系统支持创建多个CommandLineRunner或ApplicationRunner的实现类,可以使用@Order注解或实现Ordered接口,来设定各个实现类的执行顺序。

选项参数与非选项参数

  • 选项参数:可以理解为Spring Boot 提供的参数格式,以–开头,使用=分割键值对,如:java -jar XXX.jar --name=ROCKY --age=30 --spring.profiles.active=dev;
  • 非选项参数:不是以–开头,也没有设置值的单一参数KEY只有值,如:java -jar XXX.jar --name=ROCKY --age=30 --spring.profiles.active=dev 陕西 西安 雁塔区,其中"陕西 西安 雁塔区" 就是非选项参数;
  • 系统参数:-Dxxxx是设置JAVA运行上下文的参数语法,用于配置一些环境变量,如:java -jar XXX.jar -Dserver.port=8081 --name=ROCKY --age=30 --spring.profiles.active=dev 陕西 西安 雁塔区,其中"-Dserver.port"就是系统参数。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • spring mvc4中相关注解的详细讲解教程

    spring mvc4中相关注解的详细讲解教程

    这篇文章主要给大家介绍了关于spring mvc4中相关注解的相关资料,其中详细介绍了关于@Controller、@RequestMapping、@RathVariable、@RequestParam及@RequestBody等等注解的相关内容,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-06-06
  • 关于Spring配置文件加载方式变化引发的异常详解

    关于Spring配置文件加载方式变化引发的异常详解

    这篇文章主要给大家介绍了关于Spring配置文件加载方式变化引发的异常的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用Spring具有一定的参考学习价值,需要的朋友可以参考下
    2022-01-01
  • SpringAop切入点execution表达式的深入讲解

    SpringAop切入点execution表达式的深入讲解

    Spring AOP 可能会经常使用 execution切入点指示符,下面这篇文章主要给大家介绍了关于SpringAop切入点execution表达式的相关资料,需要的朋友可以参考下
    2021-08-08
  • SpringBoot如何使用applicationContext.xml配置文件

    SpringBoot如何使用applicationContext.xml配置文件

    这篇文章主要介绍了SpringBoot使用applicationContext.xml配置文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • SpringBoot实现异步事件Event详解

    SpringBoot实现异步事件Event详解

    这篇文章主要介绍了SpringBoot实现异步事件Event详解,异步事件的模式,通常将一些非主要的业务放在监听器中执行,因为监听器中存在失败的风险,所以使用的时候需要注意,需要的朋友可以参考下
    2023-11-11
  • Java 网络编程socket编程等详解

    Java 网络编程socket编程等详解

    本篇文章主要介绍了java网络编程中的类的方法以及实例,需要的朋友可以参考下
    2017-04-04
  • Spring系列中的beanFactory与ApplicationContext

    Spring系列中的beanFactory与ApplicationContext

    这篇文章主要介绍了Spring系列中的beanFactory与ApplicationContext,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • 基于@RequestBody和@ResponseBody及Stringify()的作用说明

    基于@RequestBody和@ResponseBody及Stringify()的作用说明

    这篇文章主要介绍了基于@RequestBody和@ResponseBody及Stringify()的作用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • springboot支持https请求的实现

    springboot支持https请求的实现

    本文主要介绍了springboot支持https请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Java并发编程之浅谈ReentrantLock

    Java并发编程之浅谈ReentrantLock

    今天带大家学习Java并发编程的相关知识,文中对Java ReentrantLock作了非常详细的图文示例,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05

最新评论