SpringApplicationRunListener

SpringApplicationRunListener 接口的作用主要就是在Spring Boot 啟動初始化的過程中可以通過SpringApplicationRunListener接口回調(diào)來讓用戶在啟動的各個流程中可以加入自己的邏輯。
Spring Boot啟動過程的關(guān)鍵事件(按照觸發(fā)順序)包括:

  1. 開始啟動
  2. Environment構(gòu)建完成
  3. ApplicationContext構(gòu)建完成
  4. ApplicationContext完成加載
  5. ApplicationContext完成刷新并啟動
  6. 啟動完成
  7. 啟動失敗

接口定義

下面是SpringApplicationRunListener接口定義:

package org.springframework.boot;
public interface SpringApplicationRunListener {

    // 在run()方法開始執(zhí)行時,該方法就立即被調(diào)用,可用于在初始化最早期時做一些工作
    void starting();
    // 當(dāng)environment構(gòu)建完成,ApplicationContext創(chuàng)建之前,該方法被調(diào)用
    void environmentPrepared(ConfigurableEnvironment environment);
    // 當(dāng)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);
    // 當(dāng)應(yīng)用運行出錯時該方法被調(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應(yīng)用時,就會自動將HelloApplicationRunListener實例化,并在Spring容器初始化的各個階段回調(diào)對應(yīng)的方法。
如果想知道為什么必須在spring.factories中配置,可以參考我的另一篇文章Spring Factories

org.springframework.boot.SpringApplicationRunListener=\
 com.yidian.data.listener.HelloApplicationRunListener

啟動應(yīng)用程序,輸出結(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包含三個成員變量:

  1. application:當(dāng)前運行的SpringApplication實例
  2. args:啟動命令行參數(shù)
  3. initialMulticaster:事件廣播器

在構(gòu)造EventPublishingRunListener實例的過程中,會將application關(guān)聯(lián)的所有ApplicationListener實例關(guān)聯(lián)到initialMulticaster中,以方便initialMulticaster將事件傳遞給所有的監(jiān)聽器。

  1. 當(dāng)對應(yīng)的時間處理方法被調(diào)用時,EventPublishingRunListener會將application和args封裝到對應(yīng)的SpringApplicationEvent子類實例中;
  2. initialMulticaster會根據(jù)事件類型和觸發(fā)源對事件進行分類,并與對應(yīng)的ApplicationListener建立關(guān)聯(lián)關(guān)系,之后將事件傳遞給對應(yīng)的ApplicationListener;
  3. ApplicationListener實例收到事件后,會根據(jù)時間類型不同,執(zhí)行不同的處理邏輯。

SpringApplicationEvent的繼承關(guān)系如下圖,每一個子類都對應(yīng)Spring Boot啟動過程中的一個關(guān)鍵事件。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容