SpringBoot 中使用CommandLineRunner 和 ApplicationRunner 经验分享

项目需求背景

  最近在公司做了一个和工厂有关的项目,使用的是Springboot框架集成了Redis、Swagger、Shiro等,在项目中有三个业务代码(1、实时获取噪音数据初始化;2、启动ServerSocket服务器初始化;3、海康监控布防报警初始化。)需要在项目启动后在执行,也就类似开机自启动一样。

Springboot自带两种实现方式 

  实现 CommandLineRunner 接口
  实现 ApplicationRunner 接口

两者异同点

 
CommandLineRunner 接口源码
package org.springframework.boot;
@FunctionalInterface
public interface CommandLineRunner {
void run(String... var1) throws Exception;
}

ApplicationRunner 接口源码
package org.springframework.boot;
@FunctionalInterface
public interface ApplicationRunner {
void run(ApplicationArguments var1) throws Exception;
}

瞎说:它俩表面上看结构类似,只是参数不一样,CommandLineRunner接口可以用来接收字符串数组的命令行参数,ApplicationRunner 是使用ApplicationArguments 用来接收参数的,它俩的最终实现效果是一样的,都可以让自定义的代码业务在项目启动后再执行。
CommandLineRunner 使用
/**
* 自启动业务类
**/
@Component //被spring容器管理
@Order(value = 3) //如果多个自定义ApplicationRunner,用来标明执行顺序
public class AddNoiseRunner implements CommandLineRunner {

private Logger log = LoggerFactory.getLogger(AddNoiseRunner.class);

@Override
public void run(String... strings) throws Exception {
// 自定义业务代码
}
}

CommandLineRunner 使用坑点


  该项目中,我有三个自定义业务代码需要自启动,这是时候我 实现了 CommandLineRunner 接口,并用 @Order(value = ?) 来控制他们的执行顺序,但是会出现了三个只执行了一个或者两个,也就是有的不执行的情况
后来在网上看了一位博主的文章,找到了解决方法
  参考:https://blog.csdn.net/zwq_zwq_zwq/article/details/81059017
  大体意思就是,实现 CommandLineRunner 接口的业务代码如果出现异常,会影响项目启动主线程,从而导致项目启动失败,
  所以为了互相不影响,每个实现类里的业务代码都新开一个线程,就解决了!

最终效果

@Component
@Order(value = 3)
public class AddNoiseRunner implements CommandLineRunner {

private Logger log = LoggerFactory.getLogger(AddNoiseRunner.class);

@Override
public void run(String... strings) throws Exception {
new Thread(){
public void run(){
log.info("开始实时获取噪音数据--start--getNoiseData ");
}
}.start();
}
}

ApplicationRunner 接口暂时还没用,以后用到,再继续编辑更新。
 
原文地址:https://www.cnblogs.com/Singulariity-gs/p/12765666.html