Spring容器初始化擴展點:ApplicationContextInitializer

目錄
  • 一、什么是ApplicationContextInitializer?
    • 1、核心作用
    • 2、適用場景
  • 二、ApplicationContextInitializer的使用方式
    • 1、實現ApplicationContextInitializer接口
    • 2、注冊初始化器
  • 三、ApplicationContextInitializer的執行時機
  • 四、實際應用案例
    • 1、動態設置環境變量
    • 2、注冊自定義的 Bean 定義
  • 五、注意事項
  • 六、總結

一、什么是ApplicationContextInitializer?

ApplicationContextInitializer是 Spring 框架提供的一個接口,用于在 Spring 應用上下文(ApplicationContext刷新之前對其進行自定義初始化。它允許開發者在上下文加載 Bean 定義之前,對上下文進行一些額外的配置或修改。

1、核心作用

  • 在上下文刷新之前執行自定義邏輯:例如設置環境屬性注冊自定義的 Bean 定義修改上下文配置
  • 擴展 Spring 上下文的功能:通過初始化器,可以在 Spring 啟動的早期階段介入,實現一些框架無法直接支持的功能

2、適用場景

  • 在 Spring Boot 啟動時,動態修改環境變量配置文件
  • 在上下文刷新之前,注冊自定義的 Bean后置處理器
  • 在微服務架構中,根據不同的環境(如開發、測試、生產)初始化不同的配置

二、ApplicationContextInitializer的使用方式

1、實現ApplicationContextInitializer接口

要實現一個自定義的初始化器,只需實現 ApplicationContextInitializer 接口,并重寫其 initialize 方法。

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;public class CustomContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {// 在這里編寫自定義的初始化邏輯System.out.println("CustomContextInitializer is initializing the ApplicationContext...");// 示例:設置自定義的環境變量applicationContext.getEnvironment().setActiveProfiles("dev");}
}

2、注冊初始化器

在 Spring 應用中,可以通過以下幾種方式注冊 ApplicationContextInitializer

方式 1:通過 Spring Boot 的 spring.factories 文件

src/main/resources/META-INF/spring.factories 文件中添加以下內容:

org.springframework.context.ApplicationContextInitializer=com.example.CustomContextInitializer

方式 2:通過 Spring Boot 的 SpringApplication API

在 Spring Boot 的主類中,通過 SpringApplication 注冊初始化器:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication application = new SpringApplication(MyApplication.class);application.addInitializers(new CustomContextInitializer());application.run(args);}
}

方式 3:通過 @ContextConfiguration 注解

在 Spring 測試中,可以通過 @ContextConfiguration 注解注冊初始化器:

@ContextConfiguration(initializers = CustomContextInitializer.class)
public class MyTest {// 測試代碼
}

三、ApplicationContextInitializer的執行時機

ApplicationContextInitializer 的執行時機是在 ApplicationContext 創建之后刷新之前。具體來說,它發生在以下兩個步驟之間:

  1. ApplicationContext 創建
    • 在 SpringApplication.run() 方法中,ApplicationContext 被創建,但尚未刷新
  2. ApplicationContext 刷新
    • 在 ApplicationContext 創建之后,Spring 會調用 ApplicationContextInitializerinitialize() 方法,允許開發者對上下文進行自定義初始化
    • 之后,Spring 會調用 ApplicationContext 的 refresh() 方法,正式刷新上下文

為什么在這個時機執行?

ApplicationContextInitializer 的設計目的是在上下文刷新之前,允許開發者對上下文進行一些自定義的初始化操作。這個時機的選擇有以下幾點考慮:

  • ApplicationContext 已創建:
    • 此時 ApplicationContext 已經創建,開發者可以通過 ConfigurableApplicationContext 訪問上下文,并進行一些自定義配置
  • 上下文尚未刷新:
    • 此時上下文尚未刷新,Bean 定義尚未加載,開發者可以通過 ApplicationContextInitializer 動態注冊或修改 Bean 定義

四、實際應用案例

1、動態設置環境變量

在某些場景下,可能需要根據運行環境動態設置環境變量。例如,在開發環境中啟用調試模式,在生產環境中禁用調試模式。

public class EnvironmentInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {String env = System.getProperty("env");if ("dev".equals(env)) {applicationContext.getEnvironment().setActiveProfiles("dev");} else if ("prod".equals(env)) {applicationContext.getEnvironment().setActiveProfiles("prod");}}
}

2、注冊自定義的 Bean 定義

在上下文刷新之前,可以通過 BeanDefinitionRegistry 動態注冊自定義的 Bean 定義。

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.beans.factory.config.BeanDefinition;public class CustomBeanInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext.getBeanFactory();BeanDefinition beanDefinition = ...; // 創建自定義的 BeanDefinitionregistry.registerBeanDefinition("customBean", beanDefinition);}
}

五、注意事項

  1. 執行順序
    • 如果有多個 ApplicationContextInitializer,它們的執行順序可以通過 Ordered 接口或 @Order 注解來控制
  2. 避免過早初始化
    • initialize 方法中,避免直接訪問 Bean 或執行耗時的操作,因為此時上下文尚未完全初始化

六、總結

ApplicationContextInitializer 是 Spring 框架中一個強大的擴展點,允許開發者在上下文刷新之前對其進行自定義初始化。通過合理使用 ApplicationContextInitializer,可以實現動態配置環境隔離自定義 Bean 注冊等功能,從而更好地滿足復雜的業務需求。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70557.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70557.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70557.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

hive—常用的函數整理

1、size(split(...))函數用于計算分割后字符串數組的長度 實例1&#xff09;&#xff1a;由客戶編號列表計算客戶編號個數 --數據準備 with tmp_test01 as ( select tag074445270 tag_id,202501busi_mon , 012399931003,012399931000 index_val union all select tag07444527…

vue3 采用xlsx庫實現本地上傳excel文件,前端解析為Json數據

需求&#xff1a;本地上傳excel 文件&#xff0c;但需要對excel 文件的內容進行解析&#xff0c;然后展示出來 1. 安裝依賴 首先&#xff0c;確保安裝了 xlsx 庫&#xff1a; bash復制 npm install xlsx 2. 創建 Vue 組件 創建一個 Vue 組件&#xff08;如 ExcelUpload.v…

若依框架實現動態失效時間JWT Token的實踐指南

一、功能需求背景 在前后端分離架構中&#xff0c;JWT&#xff08;JSON Web Token&#xff09;作為無狀態認證方案被廣泛使用。若依&#xff08;RuoYi&#xff09;框架的TokenService默認采用固定失效時間策略&#xff0c;但在實際開發中常需要根據業務場景動態調整Token有效期…

C++ 設計模式-策略模式

支付策略 #include <iostream> #include <memory> #include <unordered_map> #include <vector> #include <ctime>// 基礎策略接口 class PaymentStrategy { public:virtual ~PaymentStrategy() default;virtual std::string name() const 0;…

國產編輯器EverEdit - 如何在EverEdit中管理工程?

1 工程管理 1.1 應用場景 用戶創建工程后&#xff0c;會涉及到工程的管理 &#xff0c;比如&#xff1a;打開工程、關閉工程等 1.2 使用方法 1.2.1 打開工程 單擊主菜單工程 -> 打開工程&#xff0c;會彈出打開對話框&#xff0c;用戶在對話框中選擇需要打開的工程文件即…

MYSQL-數據庫-DDL-DML-DQL-DCL-基礎學習

MySql概念&#xff1a; 建立在關系模型基礎上&#xff0c;有多張相互連接的二維表組成的數據庫 SQL通用語法&#xff1a; 1.SQL語句可以單行或多行書寫&#xff0c;以分號結尾 2.SQL語句可以使用空格/縮進來增強語句的可讀性 3.MySQL數據庫的SQL語句不區分大小寫&#xff0c;關…

SpringBoot核心框架之AOP詳解

SpringBoot核心框架之AOP詳解 一、AOP基礎 1.1 AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面編程&#xff0c;面向方面編程&#xff09;&#xff0c;其實就是面向特定方法編程。 場景&#xff1a;項目部分功能運行較慢&#xff0c;定位執行耗時…

【RK3588嵌入式圖形編程】-SDL2-構建模塊化UI

構建模塊化UI 文章目錄 構建模塊化UI1、概述2、創建UI管理器3、嵌套組件4、繼承5、多態子組件6、總結在本文中,將介紹如何使用C++和SDL創建一個靈活且可擴展的UI系統,重點關注組件層次結構和多態性。 1、概述 在前面的文章中,我們介紹了應用程序循環和事件循環,這為我們的…

第四屆圖像、信號處理與模式識別國際學術會議(ISPP 2025)

重要信息 會議官網&#xff1a;www.icispp.com 會議時間&#xff1a;2025年3月28-30日 會議地點&#xff1a;南京 簡介 由河海大學和江蘇大學聯合主辦的第四屆圖像、信號處理與模式識別國際學術會議&#xff08;ISPP 2025) 將于2025年3月28日-30日在中國南京舉行。會議主…

低代碼與開發框架的一些整合[2]

1.分析的項目資源說明 經過近期的的不斷分析與運行對比&#xff0c;最終把注意力集中在了以下幾個框架&#xff1a; 01.dibootdiboot.diboot: 寫的更少, 性能更好 -> 為開發人員打造的低代碼開發平臺。Mybatis-plus關聯查詢&#xff0c;關聯無SQL&#xff0c;性能高10倍&a…

Spring Boot 中事務的用法詳解

引言 在 Spring Boot 中&#xff0c;事務管理是一個非常重要的功能&#xff0c;尤其是在涉及數據庫操作的業務場景中。Spring 提供了強大的事務管理支持&#xff0c;能夠幫助我們簡化事務的管理和控制。本文將詳細介紹 Spring Boot 中事務的用法&#xff0c;包括事務的基本概…

Java面試——Tomcat

優質博文&#xff1a;IT_BLOG_CN 一、Tomcat 頂層架構 Tomcat中最頂層的容器是Server&#xff0c;代表著整個服務器&#xff0c;從上圖中可以看出&#xff0c;一個Server可以包含至少一個Service&#xff0c;用于具體提供服務。Service主要包含兩個部分&#xff1a;Connector和…

第4章 信息系統架構(三)

4.3 應用架構 應用架構的主要內容是規劃出目標應用分層分域架構&#xff0c;根據業務架構規劃目標應用域、應用組和目標應用組件&#xff0c;形成目標應用架構邏輯視圖和系統視圖。從功能視角出發&#xff0c;闡述應用組件各自及應用架構整體上&#xff0c;如何實現組織的高階…

python小項目編程-中級(1、圖像處理)

目錄 圖像處理 實現 測試 unittest pytest 圖像處理 實現界面化操作&#xff0c;使用PIL庫實現簡單的圖像處理功能&#xff0c;如縮放&#xff08;設置縮放比例&#xff09;、旋轉和濾鏡、對比度調整、亮度調整、灰度圖、二值化圖&#xff08;二值圖如果使用的是彩色圖片需…

【Leetcode 每日一題】2209. 用地毯覆蓋后的最少白色磚塊

問題背景 給你一個下標從 0 0 0 開始的 二進制 字符串 f l o o r floor floor&#xff0c;它表示地板上磚塊的顏色。 f l o o r [ i ] floor[i] floor[i] 為 ‘0’ 表示地板上第 i i i 塊磚塊的顏色是 黑色 。 f l o o r [ i ] floor[i] floor[i] 為’1’ 表示地板上第 i …

Docker 性能優化指南

Docker 提供了強大的容器化功能&#xff0c;能夠幫助開發者在不同的環境中構建、測試和部署應用。然而&#xff0c;隨著容器化應用的不斷增長&#xff0c;Docker 容器可能會面臨一些性能瓶頸&#xff0c;影響其運行效率、資源占用和擴展能力。為了確保容器在生產環境中的高效運…

2025 WE DAY品牌日| 天璇II WE X7 Pro充電樁震撼發布,能效電氣開啟充電革命

隨著新能源產業的迅猛發展,充電樁作為電動汽車能量補給的重要基礎設施,正在成為市場關注的焦點。能效電氣作為充電樁領域的佼佼者,專注于研發高效、智能的充電解決方案,為電動汽車的普及與可持續發展鋪設了堅實的基礎。 2025年2月21日,能效電氣在深圳盛大舉辦了以“以創新 引未…

< OS 有關 > Ubuntu 24 SSH 服務器更換端口 in jp/us VPSs

原因&#xff1a; 兩臺 VPS 的 ssh 端口一直被密碼重試&#xff0c; us 這臺已經封了 632, jp 這臺兩周前清過一次 sqlite3 數據&#xff0c;現在贊到 1008 Fail2Ban 是使用 sqlite3 來記錄&#xff0c;數據量大后&#xff0c;硬盤的 I/O 會飆升&#xff0c;我有寫過一個 app…

MATLAB學習之旅:數據插值與曲線擬合

在MATLAB的奇妙世界里,我們已經走過了一段又一段的學習旅程。從基礎的語法和數據處理,到如今,我們即將踏入數據插值與曲線擬合這片充滿魅力的領域。這個領域就像是魔法中的藝術創作,能夠讓我們根據現有的數據點,構建出更加豐富的曲線和曲面,從而更好地理解和描述數據背后…

若依-@Excel新增注解numberFormat

Excel注解中原本的scale會四舍五入小數&#xff0c;導致進度丟失 想要的效果 顯示的時候保留兩個小數真正的數值是保留之前的數值 還原過程 若以中有一個專門的工具類&#xff0c;用來處理excel的 找到EXCEL導出方法exportExcel()找到writeSheet,寫表格的方法找到填充數據的方法…