SpringBoot实现多个ApplicationRunner时部分接口未执行问题

 更新时间:2023年05月16日 09:47:01   作者:惊虹上的小白  
这篇文章主要介绍了SpringBoot实现多个ApplicationRunner时部分接口未执行问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

SpringBoot多个ApplicationRunner时部分接口未执行

在springboot的项目中,需要在容器启动之后执行一些操作。springboot提供了ApplicationRunner和CommandLineRunner两个接口可以帮助我们实现这种需求。

当项目中实现了多个ApplicationRunner接口,并且其中一个使用了类似于while(true)这样不会退出的循环体。将会导致后续的ApplicationRunner接口不会被调用。

如下:

@Component
@Slf4j
public class RunnerTest1 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        while (true) {
            System.out.println("this is RunnerTest1");
            Thread.sleep(100);
        }
    }
}
@Component
@Slf4j
public class RunnerTest2 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        while (true) {
            System.out.println("this is RunnerTest2");
            Thread.sleep(100);
        }
    }
}

输出结果:

可以看到项目启动后RunnerTest2 将不会被执行。

通过分析springboot启动的源码可以发现,在applicationContext容器加载完成之后,会调用SpringApplication类的callRunners方法

该方法中会获取所有实现了ApplicationRunner和CommandLineRunner的接口bean,然后依次执行对应的run方法,并且是在同一个线程中执行。

因此如果有某个实现了ApplicationRunner接口的bean的run方法一直循环不返回的话,后续的代码将不会被执行。

ApplicationRunner实现项目启动就执行的功能

ApplicationRunner

是一个接口,常用于项目启动后,(也就是ApringApplication.run()执行结束),立马执行某些逻辑。

可用于项目的准备工作,比如加载配置文件,加载执行流,定时任务等等。

如何使用ApplicationRunner

这里有几点说明:

  • 1:这个实现类,要注入到spring容器中,这里使用了@Component注解;
  • 2:在同一个项目中,可以定义多个ApplicationRunner的实现类,他们的执行顺序通过注解@Order注解或者再实现Ordered接口来实现。
  • 3:run方法的参数:ApplicationArguments可以获取到当前项目执行的命令参数。(比如把这个项目打成jar执行的时候,带的参数可以通过ApplicationArguments获取到);
  • 4:由于该方法是在容器启动完成之后,才执行的,所以,这里可以从spring容器中拿到其他已经注入的bean。

(可以有多个实例实现该接口,但是一般需要增加注解@Order来指定加载顺序)

@Component
@Order(2)
public class JDDRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(args);
        System.out.println("这个是测试ApplicationRunner接口");
    }
}

实现ApplicationRunner接口,重写run方法,定义具体的执行逻辑

@Order注解,用于决定多个bean的执行顺序,按照值从小到大执行 (值可为负数)

  • @Order(-1)优先于@Order(0)
  • @Order(1)优先于@Order(2)

还有个接口

也可以实现和ApplicationRunner一样的功能

  • CommandLineRunner
  • CommandLineRunner接口的run方法接收的参数为String数组

总结

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

相关文章

  • 一篇文章教你使用枚举来实现java单例模式

    一篇文章教你使用枚举来实现java单例模式

    本篇文章主要介绍了Java实现单例的3种普遍的模式,饿汉式、懒汉式、枚举式。具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能给你带来帮助
    2021-07-07
  • Java中FilterInputStream和FilterOutputStream的用法详解

    Java中FilterInputStream和FilterOutputStream的用法详解

    这篇文章主要介绍了Java中FilterInputStream和FilterOutputStream的用法详解,这两个类分别用于封装输入和输出流,需要的朋友可以参考下
    2016-06-06
  • SpringBoot部署在tomcat容器中运行的部署方法

    SpringBoot部署在tomcat容器中运行的部署方法

    这篇文章主要介绍了SpringBoot部署在tomcat容器中运行的部署方法,需要的朋友可以参考下
    2018-10-10
  • Spring MVC框架配置方法详解

    Spring MVC框架配置方法详解

    这篇文章主要为大家详细介绍了Spring MVC框架的配置方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • java thread start()和run()方法简析

    java thread start()和run()方法简析

    本文以java中thread的start()和run()的区别做详细介绍, 需要了解跟多的朋友可以参考下
    2012-11-11
  • Java数组与字符串深入探索使用方法

    Java数组与字符串深入探索使用方法

    在今天的文章中,我将为你详细讲述Java学习中重要的一节 [ 数组与字符串 ] ,带你深入了解Java语言中数组的声明、创建和初始化方法,字符串的定义以及常用到的操作方法
    2022-07-07
  • 详解Java并发之Condition

    详解Java并发之Condition

    这篇文章主要介绍了Java并发编程之Condition,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Java设计模式中装饰者模式应用详解

    Java设计模式中装饰者模式应用详解

    装饰者模式:在不改变原有对象的基础之上,动态的将功能附加到对象上,提供了继承更有弹性的替代方案,也体现了开闭原则。本文将通过示例详细讲解一下装饰者模式,需要的可以参考一下
    2022-11-11
  • java 反射和动态代理详解及实例代码

    java 反射和动态代理详解及实例代码

    这篇文章主要介绍了java 反射和动态代理详解及实例代码的相关资料,需要的朋友可以参考下
    2016-09-09
  • 通过代码理解java泛型

    通过代码理解java泛型

    本篇文章通过代码实例让大家充分的理解java泛型的相关知识点内容,有需要的朋友们可以学习下。
    2018-08-08

最新评论