Spring Boot事件

一、價值

Spring Boot和Spring 事件是SpringApplication整個生命週期重要環節

二、Spring Boot事件發佈

1.切入點

Spring Boot和Spring 事件的觸發發生在SpringApplication運行階段,圍繞run(String…)方法不同階段觸發。run(String…)結合SpringApplication初始化階段完成的相關狀態,進一步完善了運行時所需要準備的資源,隨後啓動Spring應用上下文,在此期間就會伴隨Spring Boot和Spring 事件的觸發

2. 源碼(SpringBoot 2.0和1.0有一定的差別但不大,截圖爲2.0源碼):

在這裏插入圖片描述
在這裏插入圖片描述

3.SpringApplicationRunListeners:

按照源碼邏輯的實現,SpringApplicationRunListeners是有getRunListeners(String[] args)方法創建的,SpringApplicationRunListeners屬於組合模式的實現,重點在其內部關聯SpringApplicationRunListener集合
在這裏插入圖片描述

5.SpringApplicationRunListener:

SpringApplicationRunListener爲Spring Boot應用運行時監聽器,其監聽方法被SpringApplicationRunListeners迭代執行。
監聽方法有:

監聽方法 運行時階段說明 事件
starting() Spring應用剛啓動 ApplicationStartingEvent
environmentPrepared(ConfigurableEnvironment) ConfigurableEnvironment準備妥當,允許將其調整 ApplicationEnvironmentPreparedEvent
contextPrepared(ConfigurableApplicationContext) ConfigurableApplicationContext準備妥當,允許將其調整
contextLoaded(ConfigurableApplicationContext) ConfigurableApplicationContext已裝載,但未啓動 ApplicationPreparedEvent
started(ConfigurableApplicationContext) ConfigurableApplicationContext已啓動,此時Spring Bean已初始化完成 ApplicationStartedEvent
running(ConfigurableApplicationContext ) Spring應用正在運行 ApplicationReadyEvent
failed(ConfigurableApplicationContext context, Throwable exception) Spring應用運行失敗 ApplicationFailedEvent
4.SpringApplicationRunListener內建實現
  1. 結合SpringFactoriesLoader機制,能快速定位到其內建實現:EventPublishingRunListener,而且是唯一實現
    在這裏插入圖片描述
    在這裏插入圖片描述
  2. 將SpringApplication初始化階段關聯的ApplicationListener實例列表動態的添加到SimpleApplicationEventMulticaster對象中。SimpleApplicationEventMulticaster源於Spring Framework,從源碼可以看出實現ApplicationEventMulticaster接口,用於發佈Spring應用事件(ApplicationEvent)。因此EventPublishingRunListener實際是作爲Spring Boot事件發佈者在這裏插入圖片描述

四、Spring 事件發佈

  1. ApplicationEventMulticaster註冊ApplicationListener UML如下:
    在這裏插入圖片描述
    本質上就是將ApplicationEvent與ApplicationListener集合進行關聯,因此AbstractApplicationEventMulticaster#getApplicationListeners(
    ApplicationEvent event, ResolvableType eventType)方法返回event關聯ApplicationListener集合。具體可查看源碼

  2. ApplicationEventMulticaster事件廣播
    主要涉及兩個方法:multicastEvent(ApplicationEvent event)和multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType),兩個這方法均在SimpleApplicationEventMulticaster中實現並且是唯一實現。

  3. ApplicationContext事件發佈
    在這裏插入圖片描述
    從uml文件可以看出ApplicationContext的子接口ConfigurableApplicationContext提供了添加ApplicationListenner實例方法:addApplicationListener(ApplicationListener<?> listener).
    故ApplicationContext通過調用publishEvent(ApplicationEvent event)發佈事件

  4. Spring 內建事件

事件 介紹 描述
ContextRefreshedEvent Spring應用上下文就緒事件 當ConfigurableApplicationContext#refresh()方法執行到finishRefresh()方法時,發佈ContextRefreshedEvent。此時Spring應用上下文中bean均已完成初始化,可以通過監聽該事件獲取需要Bean,防止出現Bean提早初始化所帶來的的風險
ContextStartedEvent Spring應用上下文啓動事件(大多數場景基本不會觸發) AbstractApplicationContext#start()時觸發,同時能回調Lifecycle Bean的生命週期
ContextStoppedEvent Spring應用上下文停止事件(大多數場景基本不會觸發) AbstractApplicationContext#stop()時觸發,同時能回調Lifecycle Bean的生命週期
ContextClosedEvent Spring應用上下文關閉事件 ConfigurableApplicationContext#close()時觸發,由子類AbstractApplicationContext實現,執行close()後當前Spring應用上下文完全被銷燬,無法恢復(這和調用stop()有本質的區別)

5.Spring應用上下文事件ApplicationContextEvent和Spring 內建時間關係如下:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述

六、run(String…)執行過程中各事件發佈點以及順序(Spring Boot 2.0.8)

序號 監聽方法 運行時階段說明 事件
1 starting() Spring應用剛啓動 ApplicationStartingEvent
2 environmentPrepared(ConfigurableEnvironment) ConfigurableEnvironment準備妥當,允許將其調整 ApplicationEnvironmentPreparedEvent
3 prepareContext(…)->contextPrepared(ConfigurableApplicationContext) ConfigurableApplicationContext準備與裝載
4 contextLoaded(ConfigurableApplicationContext) ConfigurableApplicationContext已裝載,但未啓動 ApplicationPreparedEvent
5 refreshContext(context)->AbstractApplicationContext#rrefresh(ApplicationContext)->finishRefresh() ConfigurableApplicationContext啓動以及Spring Bean初始化,執行完畢後,Spring應用上下文正式進入Spring生命週期,Spring Boot核心特性也隨之啓動例如組件自動裝配、嵌入式容器啓動、Production-Ready特性 ContextRefreshedEvent
6 started(ConfigurableApplicationContext) ConfigurableApplicationContext已啓動,此時Spring Bean已初始化完成 ApplicationStartedEvent
7 running(ConfigurableApplicationContext ) Spring應用正在運行 ApplicationReadyEvent
8 failed(ConfigurableApplicationContext context, Throwable exception) Spring應用運行失敗 ApplicationFailedEvent

代碼驗證(Spring Boot 2.0.8)

public static void main(String[] args) {
        new SpringApplicationBuilder(Object.class)
            .listeners(event ->
                System.out.printf("監聽到事件: %s , 事件源 : %s\n"
                    , event.getClass().getSimpleName(), event.getSource())
            )
                .web(false)
                .run(args)
                .close();
    }

結果:(注意Spring Boot和Spring 事件源)
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章