SpringApplicationRunListener 接口的作用主要就是在Spring Boot 啟動初始化的過程中可以通過SpringApplicationRunListener接口回調(diào)來讓用戶在啟動的各個流程中可以加入自己的邏輯。
Spring Boot啟動過程的關鍵事件(按照觸發(fā)順序)包括:
- 開始啟動
- Environment構(gòu)建完成
- ApplicationContext構(gòu)建完成
- ApplicationContext完成加載
- ApplicationContext完成刷新并啟動
- 啟動完成
- 啟動失敗
接口定義
下面是SpringApplicationRunListener接口定義:
package org.springframework.boot;
public interface SpringApplicationRunListener {
// 在run()方法開始執(zhí)行時,該方法就立即被調(diào)用绍在,可用于在初始化最早期時做一些工作
void starting();
// 當environment構(gòu)建完成,ApplicationContext創(chuàng)建之前圆雁,該方法被調(diào)用
void environmentPrepared(ConfigurableEnvironment environment);
// 當ApplicationContext構(gòu)建完成時,該方法被調(diào)用
void contextPrepared(ConfigurableApplicationContext context);
// 在ApplicationContext完成加載帆谍,但沒有被刷新前伪朽,該方法被調(diào)用
void contextLoaded(ConfigurableApplicationContext context);
// 在ApplicationContext刷新并啟動后,CommandLineRunners和ApplicationRunner未被調(diào)用前汛蝙,該方法被調(diào)用
void started(ConfigurableApplicationContext context);
// 在run()方法執(zhí)行完成前該方法被調(diào)用
void running(ConfigurableApplicationContext context);
// 當應用運行出錯時該方法被調(diào)用
void failed(ConfigurableApplicationContext context, Throwable exception);
}
自定義SpringApplicationRunListener
我們可以通過實現(xiàn)自定義SpringApplicationRunListener來監(jiān)聽Spring Boot的啟動流程烈涮,并在各個回調(diào)方法中處理自己的邏輯。
實現(xiàn)自定義SpringApplicationRunListener需要實現(xiàn)SpringApplicationRunListener接口患雇,并且必須提供一個包含參數(shù)(SpringApplication application, String[] args)的構(gòu)造方法,如下所示:
public class HelloApplicationRunListener implements SpringApplicationRunListener {
public HelloApplicationRunListener(SpringApplication application, String[] args){
System.out.println("constructor");
}
@Override
public void starting() {
System.out.println("starting...");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
System.out.println("environmentPrepared...");
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("contextPrepared...");
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("contextLoaded...");
}
@Override
public void started(ConfigurableApplicationContext context) {
System.out.println("started...");
}
@Override
public void running(ConfigurableApplicationContext context) {
System.out.println("running...");
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("failed...");
}
}
在spring.factories中配置自定義SpringApplicationRunListener宇挫,之后在啟動Spring Boot應用時苛吱,就會自動將HelloApplicationRunListener實例化,并在Spring容器初始化的各個階段回調(diào)對應的方法器瘪。
如果想知道為什么必須在spring.factories中配置翠储,可以參考我的另一篇文章Spring Factories
org.springframework.boot.SpringApplicationRunListener=\
com.yidian.data.listener.HelloApplicationRunListener
啟動應用程序,輸出結(jié)果如下:
constructor
starting...
constructor
starting...
environmentPrepared...
contextPrepared...
contextLoaded...
started...
running...
environmentPrepared...
Spring事件觸發(fā)過程
Spring的事件觸發(fā)過程是交由SpringApplicationRunListener接口的實現(xiàn)類EventPublishingRunListener來代理實現(xiàn)的橡疼。
EventPublishingRunListener的構(gòu)造方法如下:
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
this.initialMulticaster = new SimpleApplicationEventMulticaster();
for (ApplicationListener<?> listener : application.getListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}
EventPublishingRunListener包含三個成員變量:
- application:當前運行的SpringApplication實例
- args:啟動命令行參數(shù)
- initialMulticaster:事件廣播器
在構(gòu)造EventPublishingRunListener實例的過程中援所,會將application關聯(lián)的所有ApplicationListener實例關聯(lián)到initialMulticaster中,以方便initialMulticaster將事件傳遞給所有的監(jiān)聽器欣除。
- 當對應的時間處理方法被調(diào)用時住拭,EventPublishingRunListener會將application和args封裝到對應的SpringApplicationEvent子類實例中;
- initialMulticaster會根據(jù)事件類型和觸發(fā)源對事件進行分類,并與對應的ApplicationListener建立關聯(lián)關系滔岳,之后將事件傳遞給對應的ApplicationListener杠娱;
- ApplicationListener實例收到事件后,會根據(jù)時間類型不同谱煤,執(zhí)行不同的處理邏輯摊求。
SpringApplicationEvent的繼承關系如下圖,每一個子類都對應Spring Boot啟動過程中的一個關鍵事件刘离。