当前位置: 首页 > article >正文

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 注册等功能,从而更好地满足复杂的业务需求。

相关文章:

Spring容器初始化扩展点:ApplicationContextInitializer

目录 一、什么是ApplicationContextInitializer&#xff1f;1、核心作用2、适用场景 二、ApplicationContextInitializer的使用方式1、实现ApplicationContextInitializer接口2、注册初始化器 三、ApplicationContextInitializer的执行时机四、实际应用案例1、动态设置环境变量…...

树欲静而凤不止

我不知道为什么要求一定要在抖音上举办婚礼&#xff1f;觉得唯一的一个作用&#xff0c;财力的体现。 做到了&#xff0c;就见了。让我觉得就像买见面一样。 见了不合适&#xff0c;该当如何&#xff1f; 这个对于认真找对象&#xff0c;真的很重要吗&#xff1f; 分钱给平台&…...

C++11详解(二) -- 引用折叠和完美转发

文章目录 2. 右值引用和移动语义2.6 类型分类&#xff08;实践中没什么用&#xff09;2.7 引用折叠2.8 完美转发2.9 引用折叠和完美转发的实例 2. 右值引用和移动语义 2.6 类型分类&#xff08;实践中没什么用&#xff09; C11以后&#xff0c;进一步对类型进行了划分&#x…...

AI 编程工具—Cursor 进阶篇 文章改写生成整理爬取

AI 编程工具—Cursor 进阶篇 文章改写生成整理爬取 其实对做自媒体的人而言,整理素材其实是一件非常耗时的事情,今天我们来看一下如何使用Cursor来帮我们解决这些问题,首先我们要建一个单独的项目,因为这个项目不涉及任何代码操作,只是文字相关的事情,还有就是这个项目需…...

Yageo国巨的RC系列0402封装1%电阻库来了

工作使用Cadence多年&#xff0c;很多时候麻烦的就是整理BOM&#xff0c;因为设计原理图的时候图省事&#xff0c;可能只修改value值和封装。 但是厂家&#xff0c;规格型号&#xff0c;物料描述等属性需要在最后的时候一行一行的修改&#xff0c;繁琐又容易出错&#xff0c;过…...

Linux系统安装Nginx详解(适用于CentOS 7)

目录 1. 更新系统包 2. 安装EPEL仓库 3. 安装Nginx 4. 启动Nginx服务 5. 设置Nginx开机自启 6. 检查Nginx状态 7. 配置防火墙 8. 访问Nginx默认页面 9. 配置Nginx&#xff08;可选&#xff09; 10. 重启Nginx 解决步骤 1. 检查系统版本 2. 移除错误的 Nginx 仓库 …...

Vue3 组件通信汇总

目录 1、常见通信方式汇总&#xff1a;2、常用组件通信方式说明2.1 【props】2.2【自定义事件】2.3 【v-model】2.4 【$attrs 】2.5 【\$refs、\$parent】2.6 【provide、inject】 1、常见通信方式汇总&#xff1a; Vue3组件通信和Vue2的区别&#xff1a; 移出事件总线&#…...

nginx伪静态配置解释和Nginx 常见的配置

文章目录 禁止访问 runtime 和 application 目录rewrite 对 URL 进行重写或重定向301重定向root 静态资源路径处理alias 路径映射try_files 伪静态规则Nginx 配置有许多其他常见的场景和使用方式 1. **基本的反向代理配置**2. **负载均衡配置**3. **限制访问&#xff08;IP 限…...

PromptSource和LangChain哪个更好

目录 1. 设计目标与定位 PromptSource LangChain 2. 功能对比 3. 优缺点分析 PromptSource LangChain 4. 如何选择&#xff1f; 5. 总结 PromptSource 和 LangChain 是两个在自然语言处理&#xff08;NLP&#xff09;领域非常有用的工具&#xff0c;但它们的设计目标和…...

AI安全最佳实践:AI云原生开发安全评估矩阵(下)

上篇小李哥带大家一起了解了什么是AI应用云原生开发安全评估矩阵&#xff0c;并且介绍了利用该矩阵如何确定我们云上AI应用的安全评估范围&#xff0c;接下来我们将继续本系列的下篇&#xff0c;基于该安全评估矩阵设计和实施我们系统应具备的安全控制。 优先考虑的安全控制 …...

Windows DeepSeek API调用基础教程-Python

DeepSeek API 调用&#x1f680; 在最近DeepSeek大火之后&#xff0c;在各个媒体上都能看到对这个大模型的报道&#xff0c;这个使用MoE的架构的大模型&#xff0c;在使用体验上&#xff0c;确实让我眼前一亮&#xff0c;我自己平时也是已经在用着GPT-o1&#xff0c;对比下来发…...

达梦数据库从单主模式转换为主备模式

目录标题 达梦数据库单主转主备配置笔记前期准备服务器环境数据库安装磁盘空间 流程流程图说明 详细步骤1. 检查主库归档模式2. 配置主库配置文件dm.ini 文件dmmal.ini 文件dmarch.ini 文件 3. 备份主库数据库4. 备库配置新建备库数据库配置备库配置文件dm.ini 文件复制主库的 …...

SpringUI Web高端动态交互元件库

Axure Web高端动态交互元件库是一个专为Web设计与开发领域设计的高质量资源集合&#xff0c;旨在加速原型设计和开发流程。以下是关于这个元件库的详细介绍&#xff1a; 一、概述 Axure Web高端动态交互元件库是一个集成了多种预制、高质量交互组件的工具集合。这些组件经过精…...

ES冷热数据分离配置

冷热数据是根据索引创建时间来进行迁移的。一旦迁移到冷数据节点&#xff0c;则无法再恢复成热数据&#xff0c;因为热数据节点中该索引已经没有分片存在了。 基于Docker搭建ES集群,并设置冷热数据节点 配置冷热数据迁移策略 PUT https://192.168.x.xx:19200/_ilm/policy/my…...

七大排序思想

目录 七大排序的时间复杂度和稳定性 排序 插入排序 简单插入排序 希尔排序 选择排序 简单选择排序 堆排序 交换排序 冒泡排序 快速排序 快排的递归实现 hoare版本的快排 挖坑法的快排 双指针法的快排 快排的非递归 归并排序 归并的递归实现 归并的非递归实现…...

制作PE启动盘(内含Win11 iso镜像)

前言 本文用于记录制作PE启动盘过程&#xff0c;学习记录用&#xff0c;如有不对请指出&#xff0c;谢谢&#xff01; 参考视频&#xff1a; 1. 微PE下载&#xff1a;https://www.bilibili.com/video/BV1vT4y1n7JX/?spm_id_from333.788.top_right_bar_window_history.conte…...

css字体样式与文本样式详解

目录 一、CSS字体样式 1. 字体类型&#xff08;font-family&#xff09; 2. 字体大小&#xff08;font-size&#xff09; 3. 字体粗细&#xff08;font-weight&#xff09; 4. 字体风格&#xff08;font-style&#xff09; 5. 字体颜色&#xff08;color&#xff09; 6. …...

游戏引擎学习第89天

回顾 由于一直没有渲染器&#xff0c;终于决定开始动手做一个渲染器&#xff0c;虽然开始时并不确定该如何进行&#xff0c;但一旦开始做&#xff0c;发现这其实是正确的决定。因此&#xff0c;接下来可能会花一到两周的时间来编写渲染器&#xff0c;甚至可能更长时间&#xf…...

derpseek来讲lua

Lua 是一种轻量级、高效、可嵌入的脚本语言&#xff0c;广泛应用于游戏开发、嵌入式系统、Web 服务器等领域。以下是 Lua 的主要特点和一些基本概念&#xff1a; 1. 特点 轻量级&#xff1a;Lua 的核心非常小&#xff0c;适合嵌入到其他应用程序中。高效&#xff1a;Lua 的执…...

HL7 学习(一)

一、概述&#xff1a; 1、医疗信息化是个很宽广的范围和话题&#xff0c;要实现医疗信息化&#xff0c;必须使用DICOM&#xff0c;HL7 等标准&#xff0c;加上IHE(医疗一体化)&#xff1b; 2、目前对于DICOM和IHE只是大概了解&#xff0c;知道是是干什么的&#xff0c;诸多细…...

Linux学习笔记16---高精度延时实验

延时函数是很常用的 API 函数&#xff0c;在前面的实验中我们使用循环来实现延时函数&#xff0c;但是使用循环来实现的延时函数不准确&#xff0c;误差会很大。虽然使用到延时函数的地方精度要求都不会很严格( 要求严格的话就使用硬件定时器了 ) &#xff0c;但是延时函数肯定…...

STM32HAL库RTC时钟

RTC的结构非常像一个简化版的定时器&#xff0c;核心当然是一个计数器&#xff0c;与定时器的16位计数器只能从0计数到65535不同&#xff0c;RTC的计数器是32位的&#xff0c;可以从0技术到4294967295&#xff0c;RTC的计数器前还有个RTC预分频器&#xff0c;可以将时钟源的时钟…...

Word List 2

词汇颜色标识解释 词汇表中的生词 词汇表中的词组成的搭配、派生词 例句中的生词 我自己写的生词&#xff08;用于区分易混淆的词&#xff0c;无颜色标识&#xff09; 不认识的单词或句式 单词的主要汉语意思 不太理解的句子语法和结构 Word List 2 英文音标中文regi…...

杨氏数组中查找某一数值是否存在

判断数据是否存在于杨氏矩阵中 &#xff08;小米真题&#xff09; 题目&#xff1a;有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N) …...

51单片机 02 独立按键

一、独立按键控制LED亮灭 轻触按键&#xff1a;相当于是一种电子开关&#xff0c;按下时开关接通&#xff0c;松开时开关断开&#xff0c;实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开。 #include <STC89C5xRC.H> void main() { // P20xFE;while(1){…...

AI + 编程时代,飞算JavaAI如何引领行业趋势变革

在当今科技飞速发展的浪潮下&#xff0c;AI 与编程的深度融合已成为不可阻挡的时代趋势&#xff0c;正重塑着各个行业的格局。在这场变革中&#xff0c;飞算JavaAI脱颖而出&#xff0c;凭借其卓越的特性和创新的理念&#xff0c;在 AI 编程领域展现出强大的引领力量&#xff0…...

计算机网络之物理层通信基础(电路交换、报文交换与分组交换)

一、电路交换 工作原理&#xff1a; 电路交换是在数据传输期间&#xff0c;源结点与目的结点之间建立一条由中间结点构成的专用物理连接线路&#xff0c;并在数据传输结束之前保持这条线路。整个报文的比特流连续地从源点直达终点&#xff0c;好像在一个管道中传送。 特点&am…...

Deepseek本地部署指南:在linux服务器部署,在mac远程web-ui访问

1. 在Linux服务器上部署DeepSeek模型 要在 Linux 上通过 Ollama 安装和使用模型&#xff0c;您可以按照以下步骤进行操作&#xff1a; 步骤 1&#xff1a;安装 Ollama 安装 Ollama&#xff1a; 使用以下命令安装 Ollama&#xff1a; curl -sSfL https://ollama.com/download.…...

社长的智慧

社长智慧 1. 社长智慧2. 联系方式获取方式3. 其他文章快来试试吧☺️ 1. 社长智慧 社长智慧&#x1f448;点击链接查看文章 2. 联系方式获取方式 更多文章获取做点击获取更多文章。 3. 其他文章 如果对您有帮助&#xff0c;请您点赞、收藏、关注、转发&#xff0c;让更多的…...

1-R语言概述

1.认识R语言 1.1 选择R语言的依据 免费的软件编程方便&#xff0c;语言灵活&#xff0c;图形功能强大优秀的内在帮助系统高质量、广泛的统计分析、数据挖掘平台国际上R语言已然是专业数据分析领域的标准 1.2 R的来源 ​ R是S语言的一种实现。S语言是由 AT&T贝尔实验室…...