hello,大家好,我是小黑,又和大家見面啦~~
如果你去某度搜尋關鍵詞 CommandLineRunner 初始化資源
,截止小黑同學寫這篇推文之前,大概能收到 1,030,000
個結果。
網上大部分的文章都在告訴我們說可以使用 CommandLineRunner
去初始化資源,但幾乎很少有文章告訴我們:如果 CommandLineRunner
使用不當,就會導致程式出現一些奇怪的異常,更有可能導致我們的應用直接停止執行。
正在讀這篇文章的你如果也使用了 CommandLineRunner
去初始化資源,那麼小黑同學勸你耗子尾汁,趕緊來看一下下面這些案例吧~
CommandLineRunner 執行時間太久了???
@Slf4j
@SpringBootApplication
public class CommandLineRunnerDemoApp {
private Map<String, String> map;
public static void main(String[] args) {
SpringApplication.run(CommandLineRunnerDemoApp.class, args);
}
@RestController
public class controller {
@GetMapping("/name")
public String name() {
return map.get("name");
}
}
@Bean
public CommandLineRunner commandLineRunner() {
return args -> {
// 模擬載入資料過慢
log.info("start do commandLineRunner...");
TimeUnit.MINUTES.sleep(1);
map = ImmutableMap.of("namne", "coder小黑");
log.info("do commandLineRunner end");
};
}
}
Spring 容器啟動之後,訪問 http://localhost:8080/name
,此時後臺就會直接報錯:
通過報錯資訊我們可以知道:
CommandLineRunner
在 Spring 容器起來之後開始執行,但此時 Tomcat 已經可以正常接收請求。又由於本案例中 CommandLineRunner 的執行時間過長,資料還沒有初始化完成,於是程式就開始出錯了......
CommandLineRunner 執行報錯了 ???
那如果 CommandLineRunner
在執行過程中報錯了會怎麼樣呢?
答案是:Spring 容器會自動關閉,應用會停止服務。
可能讀者會反駁小黑同學說:“CommandLineRunner
在啟動時執行,如果 CommandLineRunner
執行報錯,那就釋出失敗唄。”
其實還有更嚴重的......
當執行時間過長遇上報錯,你的應用還好嗎???
廢話不多說,直接上具體案例,先看程式碼:
@Slf4j
@SpringBootApplication
public class CommandLineRunnerDemoApp2 implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(CommandLineRunnerDemoApp2.class, args);
}
@Override
public void run(String... args) throws Exception {
log.info("start do commandLineRunner...");
// 模擬任務執行時長
TimeUnit.MINUTES.sleep(1);
// 模擬執行過程中出錯
int i = 1 / 0;
log.info("do commandLineRunner end");
}
}
執行日誌如下:
可以看到,Spring 容器一開始正常執行,系統開始對外提供服務。一分鐘之後,CommandLineRunner
在執行過程中報錯,導致 Spring 容器關閉,應用停止服務。
再多說幾句
雖然上文中這些案例都很簡單,但小黑同學在實際過程中,還真就遇到過有同學使用 CommandLineRunner
去初始化了一個很耗時的資源,而在初始化資源的時候,又不小心報錯了,於是應用就突然停止了。不過幸運的是,這次只是發生在了測試環境,線上一切正常。