CommandLineRunner並不是Spring框架原有的概念,它屬於SpringBoot應用特定的回調擴展接口:
public interface CommandLineRunner { /** * Callback used to run the bean. * @param args incoming main method arguments * @throws Exception on error */ void run(String... args) throws Exception; }
關於CommandLineRunner,我們需要關注的點有兩個:
- 所有CommandLineRunner的執行時間點是在SpringBoot應用的Application完全初始化工作之后(這里我們可以認為是SpringBoot應用啟動類main方法執行完成之前的最后一步)。
- 當前SpringBoot應用的ApplicationContext中的所有CommandLinerRunner都會被加載執行(無論是手動注冊還是被自動掃描注冊到IoC容器中)。
跟其他幾個擴展點接口類型相似,我們建議CommandLineRunner的實現類使用@org.springframework.core.annotation.Order進行標注或者實現org.springframework.core.Ordered
接口,便於對他們的執行順序進行排序調整,這是非常有必要的,因為我們不希望不合適的CommandLineRunner實現類阻塞了后面其他CommandLineRunner的執行。這個接口非常有用和重要,我們需要重點關注。
二、如果擴展
在使用SpringBoot構建項目時,我們通常有一些預先數據的加載。那么SpringBoot提供了一個簡單的方式來實現–CommandLineRunner。
1、在項目服務啟動的時候就去加載一些數據到緩存或做一些事情這樣的需求。
CommandLineRunner是一個接口,我們需要時,只需實現該接口就行。如果存在多個加載的數據,我們也可以使用@Order注解來排序。
案例:
加載數據庫數據到緩存
package com.transsnet.palmpay.controller; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; //@Component @Order(value = 1) public class MyStartupRunner2 implements CommandLineRunner { @Override public void run(String... strings) throws Exception { System.out.println(">>>>>>>>>>>>>>>服務啟動執行,執行加載數據等操作 MyStartupRunner2 order 1 <<<<<<<<<<<<<"); } }
ApplicationRunner接口也可以實現上述功能
實現的方式類似的,如下:
package com.transsnet.palmpay.controller; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Component @Order(value = -1) public class MyStartupRunner3 implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println(">>>>>>>>>>>>>>>服務啟動執行,執行加載數據等操作 MyStartupRunner3 order -1 <<<<<<<<<<<<<"); } }