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数组

总结

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

相关文章

  • hadoop分布式环境搭建过程

    hadoop分布式环境搭建过程

    这篇文章主要介绍了hadoop分布式环境搭建过程,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • Spring Boot 启动流程解析

    Spring Boot 启动流程解析

    Spring Boot 是一个简化的 Spring 应用开发框架,它以 “约定优于配置” 的理念,为开发者提供了开箱即用的功能,本文将详细剖析其内部实现,帮助你深入理解 Spring Boot 的启动机制,感兴趣的朋友跟随小编一起看看吧
    2024-12-12
  • JAVA使用反射读取注解方式

    JAVA使用反射读取注解方式

    在Java中,反射机制不仅可以操作对象的属性和方法,还可以读取注解,本文介绍了反射读取注解的步骤,包括定义注解、使用注解、通过反射获取注解信息及处理注解信息,通过具体代码例子和运行结果,详细解释了注解的定义、使用和反射获取注解的过程
    2024-09-09
  • Java基于分治算法实现的线性时间选择操作示例

    Java基于分治算法实现的线性时间选择操作示例

    这篇文章主要介绍了Java基于分治算法实现的线性时间选择操作,涉及java排序、比较、计算等相关操作技巧,需要的朋友可以参考下
    2017-11-11
  • 关于SpringBoot整合Canal数据同步的问题

    关于SpringBoot整合Canal数据同步的问题

    大家都知道canal是阿里巴巴旗下的一款开源工具,纯java开发,支持mysql数据库,本文给大家介绍SpringBoot整合Canal数据同步的问题,需要的朋友可以参考下
    2022-03-03
  • Springboot中的@Order如何使用

    Springboot中的@Order如何使用

    本文主要介绍了Springboot中的@Order如何使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 使用Netty进行编解码的操作过程详解

    使用Netty进行编解码的操作过程详解

    这篇文章主要介绍了使用Netty进行编解码的操作过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Spring Boot异步调用@Async过程详解

    Spring Boot异步调用@Async过程详解

    这篇文章主要介绍了Spring Boot异步调用@Async过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 23种设计模式(13)java观察者模式

    23种设计模式(13)java观察者模式

    这篇文章主要为大家详细介绍了23种设计模式之java观察者模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • SpringMVC实现表单验证功能详解

    SpringMVC实现表单验证功能详解

    这篇文章主要为大家详细介绍了SpringMVC 表单验证的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10

最新评论