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.mzph.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,写表格的方法找到填充数据的方法…