Springboot中ApplicationContextInitializer的使用及源码分析

news2025/2/26 11:41:16

文章目录

  • 一、认识ApplicationContextInitializer
    • 1、ApplicationContextInitializer的作用
    • 2、认识ApplicationContextInitializer接口
    • 3、ApplicationContextInitializer的常用用法
      • (1)注册BeanFactoryPostProcessor
      • (2)注册ApplicationListener监听器
      • (3)处理Environment运行环境(获取、修改配置等)
      • (4)设置ApplicationContext的parent
      • (5)注册Bean
      • (6)注册BeanPostProcessor
  • 二、使用ApplicationContextInitializer
    • 1、定义ApplicationContextInitializer实现类
    • 2、注册ApplicationContextInitializer
      • (1)在resources/META-INF/spring.factories配置
      • (2)代码注册
      • (3)配置文件注册
    • 3、查看结果
    • 4、设置执行顺序
  • 三、源码分析
    • 1、加载ApplicationContextInitializer
    • 2、执行时机
  • 参考资料

一、认识ApplicationContextInitializer

1、ApplicationContextInitializer的作用

ApplicationContextInitializer接口的执行时机:用于在刷新之前初始化Spring ConfigurableApplicationContext的回调接口。

通常在需要对应用程序上下文进行一些编程初始化的web应用程序中使用。例如,根据上下文环境注册属性源或激活概要文件

2、认识ApplicationContextInitializer接口

ApplicationContextInitializer接口只有一个方法,实现该方法会获得一个ConfigurableApplicationContext的回调。

@FunctionalInterface
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {

	void initialize(C applicationContext);

}

3、ApplicationContextInitializer的常用用法

(1)注册BeanFactoryPostProcessor

在这里插入图片描述

(2)注册ApplicationListener监听器

在这里插入图片描述

(3)处理Environment运行环境(获取、修改配置等)

在这里插入图片描述
在这里插入图片描述

(4)设置ApplicationContext的parent

在这里插入图片描述

(5)注册Bean

在这里插入图片描述

(6)注册BeanPostProcessor

在这里插入图片描述

二、使用ApplicationContextInitializer

1、定义ApplicationContextInitializer实现类

public class FirstInitializer implements ApplicationContextInitializer {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();

        Map<String, Object> map = new HashMap<>();
        map.put("key1", "First");

        MapPropertySource mapPropertySource = new MapPropertySource("firstInitializer", map);
        environment.getPropertySources().addLast(mapPropertySource);

        System.out.println("run firstInitializer");
    }

}

public class SecondInitializer implements ApplicationContextInitializer {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();

        Map<String, Object> map = new HashMap<>();
        map.put("key1", "Second");

        MapPropertySource mapPropertySource = new MapPropertySource("secondInitializer", map);
        environment.getPropertySources().addLast(mapPropertySource);

        System.out.println("run secondInitializer");
    }

}

public class ThirdInitializer implements ApplicationContextInitializer {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();

        Map<String, Object> map = new HashMap<>();
        map.put("key1", "Third");

        MapPropertySource mapPropertySource = new MapPropertySource("thirdInitializer", map);
        environment.getPropertySources().addLast(mapPropertySource);

        System.out.println("run thirdInitializer");
    }

}

2、注册ApplicationContextInitializer

(1)在resources/META-INF/spring.factories配置

org.springframework.context.ApplicationContextInitializer=com.learn.springboot.initializer.FirstInitializer

(2)代码注册

SpringApplication springApplication = new SpringApplication(SpringbootApplication.class);
springApplication.addInitializers(new SecondInitializer());
springApplication.run();

(3)配置文件注册

context.initializer.classes=com.learn.springboot.initializer.ThirdInitializer

3、查看结果

可以看到配置生效了,并且三种配置优先级不一样,配置文件优先级最高,spring.factories 其次,代码最后。

run thirdInitializer
run firstInitializer
run secondInitializer

4、设置执行顺序

可以通过@Order或者实现org.springframework.core.Ordered接口并重写setOrder方法设置顺序,@Order 值越小,执行优先级越高。

三、源码分析

springboot启动流程,手把手打断点一步步看运行步骤

1、加载ApplicationContextInitializer

在Springboot启动时,会加载所有META-INF/spring.factories中定义的ApplicationContextInitializer
在这里插入图片描述
如果用SpringApplication的addInitializers方法添加,相当于直接添加到这个List中:
在这里插入图片描述

2、执行时机

在springboot启动,调用prepareContext方法时:
在这里插入图片描述
在这里插入图片描述
所以说,initialize方法是在IOC容器启动之前执行的,此时的容器还未初始化,只能做一些容器启动前的准备工作。

参考资料

https://zhuanlan.zhihu.com/p/509824476
https://mp.weixin.qq.com/s/_kTPz22QY9fZXmyYtE-Ulw

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1477425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于StartAI本地部署相关问题解答

很多小伙伴们都有接入自己本地SD的需求&#xff0c;对此小编整理了一些相关问题~ 一、本地部署相关条件 对于想要本地部署的小伙伴要了解&#xff0c;相对于使用StartAI试用引擎本地部署更加考验电脑硬件配置备噢~ 流畅使用要nvidia显卡&#xff0c;6g以上显存&#xff08;最…

Google发布Genie硬杠Sora:通过大量无监督视频训练最终生成可交互虚拟世界

前言 Sora 问世才不到两个星期&#xff0c;谷歌的世界模型也来了&#xff0c;能力看似更强大(嗯&#xff0c;看似)&#xff1a;它生成的虚拟世界自主可控 第一部分 首个基础世界模型Genie 1.1 Genie是什么 Genie是第一个以无监督方式从未标记的互联网视频中训练的生成式交互…

浅析前端的堆栈原理以及深浅拷贝原理

浅析前端的堆栈原理以及深浅拷贝原理 首先来看一个案例 const obj {name:hzw,age:18 } let objName2 obj objName2.age 12 console.log(obj,objName2) // {name: hzw, age: 12} {name: hzw, age: 12}这里是不是很奇怪&#xff0c;为什么&#xff0c;为什么我改变objName2的…

使用 Gradle 版本目录进行依赖管理 - Android

/ 前言 / 在软件开发中&#xff0c;依赖管理是一个至关重要的方面。合理的依赖版本控制有助于确保项目的稳定性、安全性和可维护性。 Gradle版本目录&#xff08;Version Catalogs&#xff09;是 Gradle 构建工具的一个强大功能&#xff0c;它为项目提供了一种集中管理依赖…

轻松玩转Git

轻松玩转Git 快速入门什么是Git为什么要做版本控制安装git Git实战单枪匹马开始干拓展新功能小结 紧急修复bug分支紧急修复bug方案命令总结工作流 上传GitHub第一天上班前在家上传代码初次在公司新电脑下载代码下班回到家继续写代码到公司继续开发在公司约妹子忘记提交代码回家…

算法——滑动窗口之最大连续1的个数、将x减到0的最小操作数、水果成篮

3.最大连续1的个数 题目:. - 力扣&#xff08;LeetCode&#xff09; 题目要求的是给定一个二进制数组 nums 和一个整数 k&#xff0c;如果可以翻转最多 k 个 0 &#xff0c;则返回 数组中连续 1 的最大个数 。 按照题目正面去做,还要替换0,很麻烦 反正我们最后要求的是最长…

算法C++

枚举 1.化段为点 前缀和 eg:给一个数列&#xff0c;算x到y个数的和 #include <iostream> #include <vector> using namespace std;int main() {int n;cin>>n;vector<int> a(n);vector<int> sum(n1,0);for(int i0;i<n;i){scanf…

三种食物轮流吃,睡眠时间又长又香!

睡眠质量一直是人们关注的焦点&#xff0c;而饮食则被认为是影响睡眠的重要因素之一。近年来&#xff0c;有一种食物搭配方法备受瞩目&#xff0c;据说可以让人们的睡眠时间又长又香。这种方法并不复杂&#xff0c;只需要轮流食用三种特定食物&#xff0c;就能有效改善睡眠质量…

好用的AI模型集合

AI-Chat 这个网站提供的AI-Chat 3.5和AI-Chat 4.0聊天机器人&#xff0c;每天都可以免费使用。 不管是学习、工作还是日常生活&#xff0c;都能给我们带来很大的帮助&#xff0c;效率真的可以说是翻倍了。我觉得&#xff0c;如果你想让自己的生活更加高效、更加有序&#xff0…

Groovy - 大数据共享搜索配置

数据共享搜索列中配置了搜索列&#xff0c;相应的数据共享接口中也需要支持根据配置的字段搜索&#xff0c;配置实体时&#xff0c;支持搜索的入参code必须是searchKeys&#xff0c;且接口应该是需要支持分页&#xff08;入参必须是 current、pageSize&#xff09;的。current …

如何利用IP代理高效采集产品数据,打造爆品?

文章目录 一、什么是网络爬虫&#xff1f;二、普通人如何通过网络爬虫赚钱&#xff1f;2.1、心得分享2.2、工具自动化收集信息 三、 动态IP代理3.1、覆盖范围3.2、性价比3.3、教程中心F&Q使用教程 3.4、在网络数据采集中的重要性 四、实战应用案例一&#xff1a;ebay电商【…

树莓派驱动编译

驱动编译前提&#xff1a;驱动代码的编译需要提前编译号的内核 驱动&#xff08;3种实现方法&#xff0c;2条路线&#xff09;_驱动编写三种方法-CSDN博客 驱动的编写_驱动编写-CSDN博客 一、概念 1.1、驱动认识 1、裸机程序中是直接操控硬件的&#xff0c;操作系统…

【论文笔记】Attention Is All You Need

【论文笔记】Attention Is All You Need 文章目录 【论文笔记】Attention Is All You NeedAbstract1 Introduction2 Background补充知识&#xff1a;软注意力 soft attention 和硬注意力 hard attention&#xff1f;补充知识&#xff1a;加法注意力机制和点乘注意力机制Extende…

JavaScript的书写方式

JavaScript的书写方式 目前较为流行的是第二种和第三种&#xff0c;第一种很少见。在第二种和第三种推荐使用第三种&#xff0c;因为在日常开发/工作中&#xff0c;第三种是最为常见的 1.行内式 把JS代码嵌入到html元素内部 示例代码 运行效果 由于JS中字符串常量可以使用单引…

如何让电脑待机而wifi不关的操作方法!!

1、一台电脑如果一天不关机&#xff0c;大约消耗0.3度电。 一般一台电脑的功耗约为250-400W&#xff08;台式机&#xff09;。 一台电脑每月的耗电量&#xff1a;如果是每小时300W每天10小时每月30天90KW&#xff0c;即90千瓦时的电。 这只是保守估计。 2、使用完毕后正常关闭…

微调(Fine-tuning)技术概念

——微调&#xff0c;像化妆&#xff0c;一种“精细化、风格性调整”的人工美颜技能。 微调&#xff08;Fine-tuning&#xff09;是指在深度学习领域中&#xff0c;特别是针对预训练模型的一种训练策略。预先训练好的模型通常是在大规模无标注数据上通过自监督学习得到的&#…

Python股票数据,指数月线涨跌幅回测系统

1.这是我用Python写的&#xff0c;目前无法给大家直接使用exe&#xff0c;因为编译后软件不能正常使用。但是py源码可以先开源&#xff0c;给大家学习一下&#xff0c;里面的代码&#xff0c;都有我的注释&#xff0c;需要你有编程基础就可以看懂&#xff0c;自己可以在这个基础…

nginx(三)实现反向代理客户端 IP透传

正常情况下&#xff0c;客户端去访问代理服务器&#xff0c;然后代理服务器再取访问真实服务器&#xff0c;在真实服务器上&#xff0c;只能显示代理服务器的ip地址&#xff0c;而不显示客户端的ip地址&#xff0c;如果想让客户端的ip地址也能在真实服务端看见&#xff0c;这一…

程序员缺乏经验的 7 种表现!

程序员缺乏经验的 7 种表现&#xff01; 一次性提交大量代码 代码写的很烂 同时开展多项工作 性格傲慢 不能从之前的错误中学到经验 工作时间处理私人事务 盲目追逐技术潮流 知道这些表现&#xff0c;你才能在自己的程序员职业生涯中不犯相同的错误。 软件行业的工作经…

FastAPI框架整理

文章目录 一、Starlette、Pydanatic与FastAPI的关系1.Starlette1.1ASGI框架 2.Pydantic2.1基础教程1.定义接受实体2.请求参数3.可以安装插件辅助数据定义和矫正4.处理校验失败的例子5.模型的属性和方法6.解析文件7.递归模型8.ORM模型&#xff1a;从类实例创建符合ORM对象的模型…