目錄
- 一、引言
- 二、核心方法概述
- 三、加載機制
- 四、使用場景
- 五、擴展 - 如何在測試的不同階段插入邏輯
- 5.1 TestExecutionListener & AbstractTestExecutionListener
- 5.1.1 主要功能
- 5.1.2 生命周期方法
- 5.2 如何集成TestExecutionListener
- 5.3 總結
一、引言
SpringApplicationRunListener
是 Spring Boot 提供的一個接口,用于監聽 SpringApplication
的運行過程。它允許開發者在 Spring Boot 應用的不同生命周期階段插入自定義邏輯。該接口的實現類通過 SpringFactoriesLoader
加載,并且需要提供一個公共構造函數,接受 SpringApplication
實例和 String[]
參數。
二、核心方法概述
-
starting
方法
starting(ConfigurableBootstrapContext bootstrapContext)
方法在run
方法剛開始時立即調用,用于非常早期的初始化操作。default void starting(ConfigurableBootstrapContext bootstrapContext) { }
-
environmentPrepared
方法
在環境準備好但ApplicationContext
尚未創建之前調用。此方法可以用于在環境配置完成后執行邏輯。default void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,ConfigurableEnvironment environment) { }
-
contextPrepared
方法
在ApplicationContext
創建并準備好,但尚未加載資源之前調用。default void contextPrepared(ConfigurableApplicationContext context) { }
-
contextLoaded
方法
在ApplicationContext
加載完成但尚未刷新之前調用。default void contextLoaded(ConfigurableApplicationContext context) { }
-
started
方法
在上下文刷新后,應用啟動完成,但CommandLineRunner
和ApplicationRunner
尚未執���時調用。default void started(ConfigurableApplicationContext context, Duration timeTaken) { }
-
ready
方法
在run
方法即將結束時調用,此時應用上下文已刷新,所有CommandLineRunner
和ApplicationRunner
已執行。default void ready(ConfigurableApplicationContext context, Duration timeTaken) { }
-
failed
方法
如果應用啟動過程中發生異常,則調用此方法。default void failed(ConfigurableApplicationContext context, Throwable exception) { }
三、加載機制
SpringApplicationRunListener
的實現類通過 SpringFactoriesLoader
加載,開發者需要在 META-INF/spring.factories
(適用于SpringBoot2)或 META-INF/spring/org.springframework.boot.SpringApplicationRunListener
(適用于SpringBoot3) 文件中注冊實現類。
META-INF/spring.factories
示例:
org.springframework.boot.SpringApplicationRunListener=\
com.luo.MySpringApplicationRunListener
META-INF/spring/org.springframework.boot.SpringApplicationRunListener
示例:
com.luo.MySpringApplicationRunListener
四、使用場景
該接口適用于需要在 Spring Boot 啟動的不同階段插入自定義邏輯的場景,例如日志記錄、環境配置或啟動監控等。
我的使用場景是在SpringBoot啟動前執行一些擴展邏輯,所以只是重寫了SpringApplicationRunListener.starting
方法,但是在starting
方法通過org.slf4j.Logger
打印的日志沒有正常顯示(由于starting階段日志框架沒有加載完成),所以又單獨做了個日志打印工具,在starting
階段調用日志工具時將日志內容緩存起來,之后在contextPrepared
方法中統一對緩存的日志進行打印,當然你也可以直接System.out.println
進行打印…
五、擴展 - 如何在測試的不同階段插入邏輯
5.1 TestExecutionListener & AbstractTestExecutionListener
AbstractTestExecutionListener
是 Spring 框架中一個抽象類,位于 org.springframework.test.context.support
包下。它實現了 TestExecutionListener
和 Ordered
接口,主要用于在測試執行過程中提供擴展點。以下是對該類的詳細說明:
5.1.1 主要功能
-
實現
Ordered
接口:- 提供了
getOrder()
方法,默認返回Ordered.LOWEST_PRECEDENCE
,表示該監聽器的執行順序優先級最低。 - 子類可以重寫此方法以調整執行順序。
- 提供了
-
實現
TestExecutionListener
接口:- 提供了多個生命周期方法(如
beforeTestClass
、afterTestMethod
等),這些方法在測試執行的不同階段被調用。 - 默認實現是空操作(
no-op
),子類可以根據需要重寫這些方法以添加自定義邏輯。
- 提供了多個生命周期方法(如
5.1.2 生命周期方法
以下是 TestExecutionListener
接口中定義的生命周期方法及其默認實現:
beforeTestClass
:在測試類執行前調用,默認無操作。prepareTestInstance
:在測試實例準備好后調用,默認無操作。beforeTestMethod
:在每個測試方法執行前調用,默認無操作。beforeTestExecution
:在測試方法執行前調用(從 Spring 5.2 開始),默認無操作。afterTestExecution
:在測試方法執行后調用(從 Spring 5.2 開始),默認無操作。afterTestMethod
:在每個測試方法執行后調用,默認無操作。afterTestClass
:在測試類執行后調用,默認無操作。
5.2 如何集成TestExecutionListener
通過@TestExecutionListeners.listeners
引用自定義的TestExecutionListener
實現類:
@SpringBootTest
@TestExecutionListeners(listeners = MyTestExecutionListener.class, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
)
public class MyTest {@Testvoid testBiz() {}
}
5.3 總結
AbstractTestExecutionListener
是一個便于擴展的抽象類,提供了測試執行生命周期的鉤子方法,默認實現為空操作,子類可以根據需要重寫這些方法以實現自定義邏輯,同時支持通過 Ordered
接口控制執行順序。繼承該類可在測試執行的不同階段插入自定義邏輯,例如初始化資源、清理資源、記錄日志等