項目需求背景
最近在公司做了一個和工廠有關的項目,使用的是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 接口暫時還沒用,以后用到,再繼續編輯更新。