Spring Boot 啟動事件和監聽器,太強大了!

2020-12-15 51cto

大家都知道,在 Spring 框架中事件和監聽無處不在,打通了 Spring 框架的任督二脈,事件和監聽也是 Spring 框架必學的核心知識之一。

一般來說,我們很少會使用到應用程式事件,但我們也不要忘了它們的存在,比如說在 Spring 框架內部都使用了各種不同的事件來處理不同的任務。

毫無疑問,在 Spring Boot 框架中,事件和監聽也得到了發揚光大,除了常用的 Spring Framework 事件(例如:ContextRefreshedEvent)之外,Spring Boot 在啟動過程中還發送一系列其他的應用程式事件。

Spring Boot 啟動事件順序

1、ApplicationStartingEvent

這個事件在 Spring Boot 應用運行開始時,且進行任何處理之前發送(除了監聽器和初始化器註冊之外)。

2、ApplicationEnvironmentPreparedEvent

這個事件在當已知要在上下文中使用 Spring 環境(Environment)時,在 Spring 上下文(context)創建之前發送。

3、ApplicationContextInitializedEvent

這個事件在當 Spring 應用上下文(ApplicationContext)準備好了,並且應用初始化器(ApplicationContextInitializers)已經被調用,在 bean 的定義(bean definitions)被加載之前發送。

4、ApplicationPreparedEvent

這個事件是在 Spring 上下文(context)刷新之前,且在 bean 的定義(bean definitions)被加載之後發送。

5、ApplicationStartedEvent

這個事件是在 Spring 上下文(context)刷新之後,且在 application/ command-line runners 被調用之前發送。

6、AvailabilityChangeEvent

這個事件緊隨上個事件之後發送,狀態:ReadinessState.CORRECT,表示應用已處於活動狀態。

7、ApplicationReadyEvent

這個事件在任何 application/ command-line runners 調用之後發送。

8、AvailabilityChangeEvent

這個事件緊隨上個事件之後發送,狀態:ReadinessState.ACCEPTING_TRAFFIC,表示應用可以開始準備接收請求了。

9、ApplicationFailedEvent

這個事件在應用啟動異常時進行發送。

上面所介紹的這些事件列表僅包括綁定到 SpringApplication 的 SpringApplicationEvents 事件,除了這些事件以外,以下事件也會在 ApplicationPreparedEvent 之後和 ApplicationStartedEvent 之前發送:

  • WebServerInitializedEvent

這個 Web 伺服器初始化事件在 WebServer 啟動之後發送,對應的還有 ServletWebServerInitializedEvent(Servlet Web 伺服器初始化事件)、ReactiveWebServerInitializedEvent(響應式 Web 伺服器初始化事件)。

這個上下文刷新事件是在 Spring 應用上下文(ApplicationContext)刷新之後發送。

自定義啟動事件監聽器

既然我們知道了 Spring Boot 在啟動過程中的各個事件,那麼我們就可以在每個環節來處理一些我們想做的事情,只需要自定義一個監聽器來監聽某個事件就可以了。

比如我們想在上面的第 8 步,即應用啟動完成可以接收請求了,我們簡單輸出一個成功標識。

Spring Boot 基礎的構建這裡就不介紹了,如果你對 Spring Boot 還不是很熟悉,或者只是會簡單的使用,那還是建議你深入學習下吧,推薦這個 Spring Boot 學習倉庫,歡迎 Star 關注:

https://github.com/javastacks/spring-boot-best-practice

1、新建監聽器

  1. import lombok.extern.slf4j.Slf4j; 
  2. import org.springframework.boot.availability.AvailabilityChangeEvent; 
  3. import org.springframework.boot.availability.ReadinessState; 
  4. import org.springframework.context.ApplicationListener; 
  5.  
  6. /** 
  7.  * 來源微信公眾號:Java技術棧 
  8.  */ 
  9. @Slf4j 
  10. public class JavastackListener implements ApplicationListener<AvailabilityChangeEvent> { 
  11.  
  12.     @Override 
  13.     public void onApplicationEvent(AvailabilityChangeEvent event) { 
  14.         log.info("監聽到事件:" + event); 
  15.         if (ReadinessState.ACCEPTING_TRAFFIC == event.getState()){ 
  16.             log.info("應用啟動完成,可以請求了……"); 
  17.         } 
  18.     } 
  19.  

新建一個自定義監聽器,實現了 ApplicationListener 接口,泛型 AvailabilityChangeEvent 表示僅僅監聽 AvailabilityChangeEvent 事件。

因第 8 步的事件和第 6 步的事件同名,我們可以根據事件的狀態來區分到底是哪一個環節的事件 。

2、註冊監聽器

註冊監聽器有兩種方式:

1、在資源目錄中的 META-INF/spring.factories 文件中自動註冊:

  1. org.springframework.context.ApplicationListener=\ 
  2. cn.javastack.springboot.features.listener.JavastackListener 

2、如果是監聽 Spring 應用上下文(ApplicationContext)創建之後的事件,可以直接在監聽器上使用 @Component 註解即可,否則需要使用第一種方法的自動註冊,因為 ApplicationContext 並未創建,這時的 Bean 是不能被加載的。

3、應用啟動

下面來看下啟動日誌:

可以看到同時輸出了第 6 步和 8 步的監聽日誌,但只輸出第 8 步的啟動完成日誌,自定義監聽實現成功。

總結

了解了 Spring Boot 啟動過程中的各個事件及監聽機制,大家可以依葫蘆畫瓢實現 Spring Boot 啟動過程中的各個自定義操作,比如說在啟動過程上實現動態註冊、移除 Bean 等。

一般來說,不建議使用事件和監聽器來實現比較耗時和繁重的任務,這樣會影響應用程式的正常啟動,考慮使用 Spring Boot 的 application/ command-line runners 來進行實現。

本文只是介紹了一下 Spring Boot 啟動過程中的事件及如何實現自定義監聽器,怎麼實現一個業務上的自定義事件和監聽器不在本文範圍之類,後續棧長再開一篇,關注公眾號Java技術棧第一時間推送,不要走開。

本文實踐所有原始碼已上傳:

https://github.com/javastacks/spring-boot-best-practice

參考資料:

https://docs.spring.io/spring-boot/docs/2.3.5.RELEASE/reference/htmlsingle/#boot-features-application-events-and-listeners

本文轉載自微信公眾號「 Java技術棧」,可以通過以下二維碼關注。轉載本文請聯繫 Java技術棧公眾號。

【編輯推薦】

【責任編輯:

武曉燕

TEL:(010)68476606】

點讚 0

相關焦點

  • Spring Boot Admin快速打造監控平臺
    Spring Boot Admin快速打造監控平臺 使用過Spring boot的開發者都知道actuator,它是Springboot提供的用來對應用系統進行自省和監控的功能模塊,藉助於Actuator開發者可以很方便地對應用系統某些監控指標進行查看、統計等。
  • 史上最全spring boot實戰文檔,吃透這些,面試幹掉80%對手
    SpringBoot的意義在於它繼承了Spring的過去優點,ioc,aop,springmvc,而且快速啟動伺服器,快速開發單個微服務。最大的重要性是:springcloud是一個基於springboot實現的一系 列框架的集合,用來提供全局的服務治理方案。springcloud要基於springboot來實現,離不開springboot。
  • 「純手打」2萬字長文從0開始Spring Boot(上)
    引入 Spring MVC首先,我們打開 Maven 中 SpringBoot的官方倉庫:https://mvnrepository.com/artifact/org.springframework.boot該倉庫包含了近乎所有官方支持的 Starter 依賴,你可以理解 Starter 依賴是遵循 SpringBoot
  • Spring Boot面試題(2020最新版)
    spring boot 核心配置文件是什麼?bootstrap.properties 和 application.properties 有何區別 ?功能強大;Shiro 功能簡單Spring Boot 中如何解決跨域問題 ?
  • 基礎篇:Spring Boot入門體驗(圖文教程)
    用大佬的話來理解,就是 spring boot 其實不是什麼新的框架,它默認配置了很多框架的使用方式,就像 maven 整合了所有的 jar 包,spring boot 整合了所有的框架,總結一下及幾點:(1)為所有 Spring 開發提供一個更快更廣泛的入門體驗。(2)零配置。無冗餘代碼生成和XML 強制配置,遵循「約定大於配置」 。
  • 詳解SpringCloud中RabbitMQ消息隊列原理及配置,一篇就夠!
    rabbitmq已經被spring-boot做了整合訪問實現。spring cloud也對springboot做了整合邏輯。所以rabbitmq的依賴可以在spring cloud中直接使用。Consumer則負責註冊一個隊列監聽器,來監聽隊列的狀態,當隊列狀態發生變化時,消費消息。註冊隊列監聽需要提供交換器信息,隊列信息和路由鍵信息。這種交換器通常用於點對點消息傳輸的業務模型中。如電子郵箱。
  • Spring boot 基於註解方式配置datasource
    Spring boot 基於註解方式配置datasourceXml配置我們先來回顧下,使用xml配置數據源。boot基於註解方式怎麼配置數據源。先了解這幾個註解之後,我們就可以開始寫代碼了(在文章最後,凱哥會把xml和註解的對應關系列出來,方便大家理解)。
  • 芋道 Spring Boot JPA 入門(一)之快速入門
    >org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>
  • Spring Boot 節省95%內存佔用
    GraalVM[1] 是一種高性能的虛擬機,它可以顯著的提高程序的性能和運行效率,非常適合微服務。最近比較火的 Java 框架 Quarkus[2] 默認支持 GraalVM下圖為 Quarkus 和傳統框架(SpringBoot) 等對比圖,更快的啟動數據、更小的內存消耗、更短的服務響應。
  • 深入淺出Spring 5,使用Spring 5的反應式WebSocket
    WebSocket是一種眾所周知的協議,它支持客戶端和伺服器之間的全雙工通信,通常用於Web應用程式中,其中客戶端和伺服器需要以高頻率和低延遲交換事件。Spring Framework 5在框架中具有現代化的WebSockets支持,從而為該通信通道添加了響應功能。
  • Spring Boot實現定時任務新解,你是否能get到?
    在日常的開發過程中經常使用到定時任務,在springMVC的開發中,經常和quartz框架進行集成使用,但在springboot中沒有這麼做,而是使用了java的線程池來實現定時任務。一、概述在springboot中使用定時任務非常簡單,只需要簡單的幾步即可完成。
  • 5步學完spring boot單元測試,與postman有什麼優點?
    今天就來搭建一下spring boot的單元測試,再來感受他們各自的優點。1、添加依賴2、創建父類在項目裡有可能會出現下面的情況,也就是idea並沒有把test文件夾下面的文件當成源文件,解決步驟也簡單。兩步搞定:a、首先在File下的Project Strncture 如下圖。
  • 利用Spring Boot Admin 進行項目監控管理
    作者: 周二鴨 出處:https://www.cnblogs.com/jojop/p/11392117.html 一、Spring Boot Admin 是什麼 Spring Boot Admin (SBA) 是一個社區開源項目,用於管理和監視
  • springboot2.1.5集成fineReport報表工具
    在pom.xml中設置打包時將項目中libs文件夾下的jar也打包進去<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin
  • 如何用Spring WebFlux構建Reactive REST API
    異步和無阻塞 → 響應式編程為編寫異步和非阻塞應用程式提供了靈活性。事件/消息驅動 → 系統能夠為任何活動生成對應的事件或消息。例如,那些來自資料庫的數據會被視為事件流。它能夠提供兩個響應式和可組合的API,即:Flux [N]和Mono [0|1]。它們廣泛地實現了響應式擴展(Reactive Extensions)。Reactor為HTTP(包括Websocket)提供了非阻塞的背壓式網絡引擎、TCP和UDP。它也非常適合於微服務的架構。
  • 使用Spring Boot,Angular 6和Maven構建Web應用程式
    使用Maven 組合Spring Boot和Angular可能是一項具有挑戰性的任務。在這篇文章中,我們將使用Spring Boot和Angular 6創建一個簡單的Web應用程式,並將它們打包在一個war文件中。創建Maven項目首先,創建一個包含兩個模塊的Maven項目:一個用於後端,另一個用於前端。
  • 細品 Spring Boot+Thymeleaf,還有這麼多好玩的細節!
    </groupId>    <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency>    <groupId>org.springframework.boot</groupId>
  • java spring boot 面試題 高級 bean 生命周期
    java spring boot 面試題 高級 bean 生命周期過程如下, 核心步驟為如下高亮四步.