我們在平時的springboot專案中會遇到在服務啟動時期望其載入某些靜態檔案,或者服務啟動時訪問某些其他服務。這時候就需要在springboot中配置啟動執行。
springboot為我們提供了兩種開機啟動的介面
- CommandLineRunner
- ApplicationRunner
- 同時我們也可以採用spring提供的監聽事件ApplicationListener來實現 幾種種方式都可以實現“開機啟動”。
CommandLineRunner實現
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(1)
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("this is MyCommandLineRunner");
}
}
複製程式碼
ApplicationRunner實現
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(2)
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("this is MyApplicationRunner");
}
}
複製程式碼
ApplicationListener實現
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
System.out.println("this is MyApplicationListener");
}
}
複製程式碼
執行結果
2018-09-24 18:21:25.017 INFO 7896 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
this is MyApplicationListener
Disconnected from the target VM, address: '127.0.0.1:12936', transport: 'socket'
2018-09-24 18:21:25.040 INFO 7896 --- [ main] c.e.s.SpringBootExamplesApplication : Started SpringBootExamplesApplication in 2.89 seconds (JVM running for 5.734)
this is MyCommandLineRunner
this is MyApplicationRunner
複製程式碼
其中ApplicationStartListener的onApplicationEvent方法在容器啟動時已經被成功呼叫了。而此時初始化的容器為root容器。
此處使用Spring boot來進行操作,沒有出現二次呼叫的問題。在使用傳統的application.xml和project-servlet.xml配置中會出現二次呼叫的問題。主要原因是初始化root容器之後,會初始化project-servlet.xml對應的子容器。我們需要的是隻執行一遍即可。那麼上面列印父容器的程式碼用來進行判斷排除子容器即可。在業務處理之前新增如下判斷:
if(contextRefreshedEvent.getApplicationContext().getParent() != null){
return;
}
複製程式碼
這樣其他容器的初始化就會直接返回,而父容器(Parent為null的容器)啟動時將會執行相應的業務操作。
而CommandLineRunner與ApplicationRunner在Spring Beans初始化之後執行,執行順序可以實現order介面或者註解@order來標記,@order(1),其中數字代表執行順序,1是第一個,2是第二個,以此類推。