4.Spring Context 装载过程源码分析
Spring的ApplicationContext是Spring框架中的核心接口之一,它扩展了BeanFactory接口,提供了更多的高级特性,如事件发布、国际化支持、资源访问等。ApplicationContext的装载过程是Spring框架中非常重要的一个环节。以下是ApplicationContext装载过程的源码分析:
1. 创建ApplicationContext实例
 装载过程的第一步是创建一个ApplicationContext的实例。这通常通过调用ClassPathXmlApplicationContext、FileSystemXmlApplicationContext或AnnotationConfigApplicationContext等具体实现类的构造函数来完成。
ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);
 2. 初始化BeanFactory
 在ApplicationContext的实现类中,装载过程首先会初始化一个DefaultListableBeanFactory实例,这是BeanFactory的一个具体实现。
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
 3. 设置BeanFactory属性
 接着,ApplicationContext会设置BeanFactory的一些属性,如类加载器、Bean表达式解析器等。
beanFactory.setBeanClassLoader(getClassLoader());
 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory));
 4. 注册BeanPostProcessors
 ApplicationContext会注册所有的BeanPostProcessor实现类。这些处理器会在Bean的初始化前后被调用。
beanFactory.addBeanPostProcessor(new MyBeanPostProcessor());
 5. 装载Bean定义
 根据ApplicationContext的具体实现,它会从不同的源装载Bean定义。例如,ClassPathXmlApplicationContext会从类路径下的XML文件中装载Bean定义。
loadBeanDefinitions(beanFactory);
 6. 初始化MessageSource
 如果需要,ApplicationContext会初始化一个MessageSource用于国际化。
initMessageSource();
 7. 初始化应用事件多播器
 ApplicationContext会初始化一个应用事件多播器,用于事件发布和监听。
initApplicationEventMulticaster();
 8. 注册事件监听器
 注册所有的事件监听器。
registerEventListeners();
 9. 初始化其他基础设施
 初始化其他Spring框架的基础设施,如ResourcePatternResolver等。
10. 调用BeanFactory的preInstantiateSingletons方法
 这个方法会触发所有剩余的非懒加载的单例Bean的初始化。
beanFactory.preInstantiateSingletons();
 11. 调用refresh()方法
 最后,ApplicationContext会调用自身的refresh()方法来完成装载过程。这个方法会执行上述所有步骤,并确保容器完全初始化和就绪。
public void refresh() throws BeansException, IllegalStateException {
 // …
 }
 refresh()方法是装载过程的核心,它协调了容器的初始化和Bean的创建。通过分析refresh()方法的源码,我们可以深入理解Spring容器是如何工作的。
请注意,上述步骤可能会根据不同的ApplicationContext实现类和配置有所变化。此外,Spring框架的版本更新也可能带来一些实现上的变化。上述分析基于Spring框架的一般装载过程。
BeanFactoryPostProcessor源码分析
BeanFactoryPostProcessor是Spring框架中的一个重要接口,它允许开发者在容器实例化和属性赋值完成后,初始化Bean之前,执行一些自定义逻辑。BeanFactoryPostProcessor接口定义了一个方法:
public interface BeanFactoryPostProcessor {
 void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
 }
 源码分析
 在Spring容器初始化过程中,BeanFactoryPostProcessor的逻辑主要在AbstractApplicationContext类中实现。以下是源码分析的关键点:
注册BeanFactoryPostProcessor: 在容器初始化时,所有的BeanFactoryPostProcessor实现类都会被注册到容器中。
调用postProcessBeanFactory: 在BeanFactory的标准初始化之后,容器会调用所有注册的BeanFactoryPostProcessor的postProcessBeanFactory方法。这个方法允许开发者查看和修改BeanFactory中的Bean定义。
修改Bean定义: 在postProcessBeanFactory方法中,开发者可以添加新的Bean定义、修改现有Bean定义、或者删除某些Bean定义。
应用顺序: BeanFactoryPostProcessor的实现类可以定义它们的应用顺序。如果需要,可以通过实现Ordered接口或使用@Order注解来指定顺序。
调用时机: BeanFactoryPostProcessor的调用发生在Bean的属性赋值之后,初始化之前。这意味着,此时Bean的属性已经设置完成,但Bean还没有被初始化。
异常处理: 如果在BeanFactoryPostProcessor的调用过程中抛出了异常,容器会捕捉这个异常,并传播出去。
与BeanPostProcessor的区别: BeanFactoryPostProcessor作用于BeanFactory,而BeanPostProcessor作用于具体的Bean。BeanFactoryPostProcessor可以在Bean初始化之前对BeanFactory进行修改,而BeanPostProcessor可以在Bean的初始化过程中插入自定义逻辑。
示例
 下面是一个简单的BeanFactoryPostProcessor实现示例,它在BeanFactory初始化后打印所有Bean定义的名称:
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {String[] beanNames = beanFactory.getBeanDefinitionNames();System.out.println("Bean names after BeanFactoryPostProcessor: ");for (String beanName : beanNames) {System.out.println(beanName);}
}
 
}
 通过实现BeanFactoryPostProcessor接口,开发者可以在Spring容器初始化Bean之前,对BeanFactory进行自定义操作,这为实现一些高级特性提供了可能,例如自动装配、Bean定义的动态修改等。
BeanDefinitionRegistryPostProcessor源码分析
BeanDefinitionRegistryPostProcessor 是 Spring 框架中的一个接口,它扩展了 BeanFactoryPostProcessor 接口。与 BeanFactoryPostProcessor 相比,BeanDefinitionRegistryPostProcessor 提供了对 BeanDefinitionRegistry 的访问,允许在 post-processing 阶段注册新的 BeanDefinition。这使得开发者可以在容器的 BeanDefinition 加载完成之后、实例化 Bean 之前,动态地添加或修改 BeanDefinition。
以下是 BeanDefinitionRegistryPostProcessor 接口的定义:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/*** 在 BeanFactoryPostProcessor 的 postProcessBeanFactory 调用之后调用。* 允许在 BeanDefinitionRegistry 中注册更多的BeanDefinition。* @param registry BeanDefinitionRegistry 的实例* @throws org.springframework.beans.BeansException*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
 
}
 源码分析
 扩展 BeanFactoryPostProcessor:BeanDefinitionRegistryPostProcessor 接口继承自 BeanFactoryPostProcessor,因此它拥有 postProcessBeanFactory 方法的能力,并且可以访问 ConfigurableListableBeanFactory。
postProcessBeanDefinitionRegistry 方法:这是 BeanDefinitionRegistryPostProcessor 的核心方法,它允许开发者在 BeanDefinitionRegistry 中注册新的 BeanDefinition 或修改现有的 BeanDefinition。
调用时机:postProcessBeanDefinitionRegistry 方法在 postProcessBeanFactory 方法之后调用,确保开发者在注册新的 BeanDefinition 时,已有的 BeanDefinition 已经加载完成。
BeanDefinitionRegistry:BeanDefinitionRegistry 是一个接口,它定义了注册、移除和获取 BeanDefinition 的方法。postProcessBeanDefinitionRegistry 方法提供了对 BeanDefinitionRegistry 的访问,使得开发者可以操作 BeanDefinition。
BeanDefinition 的动态注册:开发者可以在 postProcessBeanDefinitionRegistry 方法中使用 BeanDefinitionRegistry 的 registerBeanDefinition 方法来注册新的 BeanDefinition。
BeanDefinition 的修改:除了注册新的 BeanDefinition,开发者还可以修改现有的 BeanDefinition,例如更改 Bean 的作用域、添加属性等。
异常处理:如果在 postProcessBeanDefinitionRegistry 方法中抛出异常,容器会捕捉这个异常并传播出去,这可能会中断 Bean 的创建过程。
示例
 下面是一个简单的 BeanDefinitionRegistryPostProcessor 实现示例,它在 BeanDefinitionRegistry 中注册一个新的 BeanDefinition:
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// 可以在这里访问和修改 beanFactory
}@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {// 注册一个新的 BeanDefinitionRootBeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);registry.registerBeanDefinition("myBean", beanDefinition);
}
 
}
 通过实现 BeanDefinitionRegistryPostProcessor 接口,开发者可以在 Spring 容器的 BeanDefinition 加载完成后,动态地注册或修改 BeanDefinition,这为实现一些复杂的配置和自定义行为提供了强大的支持。
相关文章:
4.Spring Context 装载过程源码分析
Spring的ApplicationContext是Spring框架中的核心接口之一,它扩展了BeanFactory接口,提供了更多的高级特性,如事件发布、国际化支持、资源访问等。ApplicationContext的装载过程是Spring框架中非常重要的一个环节。以下是ApplicationContext装…...
mysql之数据存储单元
简介 在MySQL中,单行数据存储单元的大小并不是固定的,它取决于多种因素,如表结构中使用的数据类型以及所使用的存储引擎。 但是我们可以提供一些关于MySQL中典型行数据存储单元大小的一般性指引: 存储引擎 InnoDB(默认存储引擎) InnoDB中单行数据存储单元的大小通常在8-16…...
未来20年人工智能将如何塑造社会
照片由Brian McGowan在Unsplash上拍摄 更多资讯,请访问 2img.ai “人工智能会成为我们的救星还是我们的末日?” 几十年来,这个问题一直困扰着哲学家、科学家和科幻爱好者。 当我们踏上技术革命的边缘时,是时候透过水晶球&#x…...
Maven的依赖传递、依赖管理、依赖作用域
在Maven项目中通常会引入大量依赖,但依赖管理不当,会造成版本混乱冲突或者目标包臃肿。因此,我们以SpringBoot为例,从三方面探索依赖的使用规则。 1、 依赖传递 依赖是会传递的,依赖的依赖也会连带引入。例如在项目中…...
ArcGIS定义1.5度带坐标系与投影转换
 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 对于ArcGIS如何定义高斯克吕格3度带、6度带,我相信大部分人都是比较清楚的࿰…...
艺术与科技的精湛融合:探讨AI绘画与AI动画的交汇点
前言 艺术与科技的精湛融合:探讨AI绘画与AI动画的交汇点 在当代社会中,艺术和科技的结合呈现出了从来灭有的创新和可能性。随着人工智能技术的不断发展,AI绘画与AI动画的融合愈发引人瞩目。这一融合不仅给艺术家们带来了更多创作的可能&…...
【移动应用开发期末复习】第五/六章
系列文章 第一章——Android平台概述 第一章例题 第二章——Android开发环境 第二章例题 第三章 第三章例题 第四章 系列文章界面布局设计线性布局表格布局帧布局相对布局约束布局控制视图界面的其他方法代码控制视图界面数据存储与共享首选项信息数据文件SQLite数据库Content…...
excel FORMULA
在Excel中,FORMULA 实际上是一个拼写错误。您可能是指 FORMULA 的正确拼写 FORMULA(这在Excel中不是有效的函数或关键字),但更可能是您想要讨论的是FORMULA(公式)的创建或使用。 在Excel中,您可…...
【学习】开发板接口
工作用到机器的开发板 有如上三个接口 。最右是仿真器,中间是RS232串口,最左是电源线 仿真器 这个是仿真器 接入机器那端用的是SWD模式,另一端通过USB接电脑(这小肥手拍的怪好看)仿真口连接了四条线分别是 VCC&#…...
主干网络篇 | YOLOv5/v7 更换骨干网络之 EfficientNet | 卷积神经网络模型缩放的再思考
主干网络篇 | YOLOv5/v7 更换骨干网络之 EfficientNet | 卷积神经网络模型缩放的再思考 1. 简介 近年来,深度卷积神经网络(CNN)在图像识别、目标检测等领域取得了巨大进展。然而,随着模型复杂度的不断提升,模型训练和…...
如何测试Java应用的性能?
如何测试Java应用的性能? 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 在开发Java应用程序的过程中,性能测试是一个不可忽视的重要环…...
css 动画
当涉及到CSS动画时,有几种方式可以实现动画效果。以下是一些常见的CSS动画技术: 使用keyframes规则:keyframes规则允许你创建一个动画序列,定义动画的关键帧和属性值。例如,你可以创建一个旋转动画,让一个…...
# 设置 Linux 安全策略允许本地 IP 开通了访问权限
设置 Linux 安全策略允许本地 IP 开通了访问权限 在 Linux 中设置安全策略通常涉及使用 iptables 或者 firewalld( 在较新的 Red Hat/CentOS 版本中)。以下是使用 iptables 允许特定本地 IP 访问的例子: 1、先清除现有的规则(谨…...
C++初学者指南第一步---14.函数调用机制
C初学者指南第一步—14.函数调用机制 文章目录 C初学者指南第一步---14.函数调用机制1.记住:内存的结构2.函数调用是如何工作的3. 不要引用局部变量4. 常见编译器优化5. Inlining内联 1.记住:内存的结构 堆(自由存储) 用于动态存…...
Apache Flink类型及序列化研读生产应用|得物技术
一、背景 序列化是指将数据从内存中的对象序列化为字节流,以便在网络中传输或持久化存储。序列化在Apache Flink中非常重要,因为它涉及到数据传输和状态管理等关键部分。Apache Flink以其独特的方式来处理数据类型以及序列化,这种方式包括它…...
如何使用代理 IP 防止多个 Facebook 帐户关联 - 最佳实践
在社交媒体被广泛应用的今天,Facebook作为全球最大的社交网络平台之一,面临着很多挑战,其中之一就是用户行为的管理和安全。 为了防止多个账户之间的关联和滥用,Facebook需要采取一系列措施,其中包括使用静态住宅代理…...
DDei在线设计器-API-DDeiAbstractShape
DDeiAbstractShape DDeiAbstractShape代表是所有可见图形的父类,定义了图形所需要的公共属性和方法。 DDeiAbstractShape实例包含了一个图形的所有数据和渲染器,在获取后可以通过它访问其他内容。DDeiAbstractShape中的layer指向所在图层,stage指向所…...
IPython的使用技巧整理
关于IPython的使用技巧有很多,这里只是梳理了几个常用的以及我目前遇到过的,其他的技巧还没使用过,所以就没有列出来。 01|Tab键自动完成:在shell中输入表达式时,只要按下Tab键,当前命名空间中任何与已输入的字符串相…...
vue项目纯前端实现导出pdf文件
1、下载插件 npm install html2canvas npm install jspdf2、创建htmlToPdf.js,地址:src/utils/htmlToPdf.js import html2Canvas from html2Canvas import JsPDF from jspdf export default { install(Vue, options) { Vue.prototype.getPdfFromH…...
以Bert训练为例,测试torch不同的运行方式,并用torch.profile+HolisticTraceAnalysis分析性能瓶颈
以Bert训练为例,测试torch不同的运行方式,并用torch.profileHolisticTraceAnalysis分析性能瓶颈 1.参考链接:2.性能对比3.相关依赖或命令4.测试代码5.HolisticTraceAnalysis代码6.可视化A.优化前B.优化后 以Bert训练为例,测试torch不同的运行方式,并用torch.profileHolisticTra…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
