Springboot啟動時執行指定程式碼

紅燒鯉魚發表於2018-09-24

我們在平時的springboot專案中會遇到在服務啟動時期望其載入某些靜態檔案,或者服務啟動時訪問某些其他服務。這時候就需要在springboot中配置啟動執行。

springboot為我們提供了兩種開機啟動的介面

  1. CommandLineRunner
  2. ApplicationRunner
  3. 同時我們也可以採用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是第二個,以此類推。

相關文章