Mr. Cappuccino的第63杯咖啡——Spring之AnnotationConfigApplicationContext源码分析

news2024/11/25 19:17:47

Spring之AnnotationConfigApplicationContext源码分析

    • 源码分析

源码分析

以上一篇文章《Spring之Bean的生命周期》的代码进行源码分析

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig02.class);
LifeCycleBean lifeCycleBean = applicationContext.getBean("lifeCycleBean", LifeCycleBean.class);
System.out.println("-----------------------------------");
System.out.println("LifeCycleBean " + lifeCycleBean);
System.out.println("-----------------------------------");
applicationContext.close();

new AnnotationConfigApplicationContext(SpringConfig02.class)

AnnotationConfigApplicationContext.java

在这里插入图片描述

AbstractApplicationContext.java

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// 容器刷新前的准备工作,例如对系统属性、环境变量进行准备及验证
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		// 初始化BeanFactory
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		// 对BeanFactory进行属性填充及功能填充,例如添加某些BeanPostProcessor以实现某些功能(ApplicationContextAwareProcessor)
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			// 空方法,用于子类实现扩展功能
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			// 执行BeanFactoryPostProcessor,例如ConfigurationClassPostProcessor、EventListenerMethodProcessor以及某些自定义的BeanFactoryPostProcessor
			// ConfigurationClassPostProcessor用于处理配置类,会将配置类中需要注册的Bean对象的元数据解析并存入beanDefinitionMap集合中
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			// 注册BeanPostProcessor,例如AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor以及某些自定义的BeanPostProcessor
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			// 初始化消息资源,国际化处理
			initMessageSource();

			// Initialize event multicaster for this context.
			// 初始化消息多播器
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// 空方法,用于子类实现扩展功能
			onRefresh();

			// Check for listener beans and register them.
			// 注册所有的ApplicationListener到消息多播器
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// 实例化、初始化剩下的非懒加载的单例对象
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// 完成刷新动作,启动LifecycleProcessor,发布ContextRefreshedEvent事件
			finishRefresh();
		}

		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			// Destroy already created singletons to avoid dangling resources.
			// 销毁已创建的单例对象
			destroyBeans();

			// Reset 'active' flag.
			cancelRefresh(ex);

			// Propagate exception to caller.
			throw ex;
		}

		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
		}
	}
}

BeanFactory中两个重要的对象

DefaultListableBeanFactory.java

/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

DefaultSingletonBeanRegistry.java

/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

Debug源码分析

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

register(componentClasses):注册指定的配置类SpringConfig02到beanDefinitionMap集合中

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

invokeBeanFactoryPostProcessors(beanFactory):创建BeanFactoryPostProcessor接口相关实现类的实例对象并存入singletonObjects集合中;执行BeanFactoryPostProcessor接口相关实现类的方法,通过ConfigurationClassPostProcessor处理配置类中需要注册的bean对象,并将bean对象注册到beanDefinitionMap集合中。

在这里插入图片描述

registerBeanPostProcessors(beanFactory):注册BeanPostProcessor接口相关实现类,创建BeanPostProcessor接口相关实现类的实例对象并存入singletonObjects集合中

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

finishBeanFactoryInitialization(beanFactory):实例化、初始化剩下的非懒加载的单例对象并存入singletonObjects集合中

在这里插入图片描述

beanFactory.preInstantiateSingletons():提前加载单例对象


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

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

相关文章

通达信接口调用过程需要借助什么?

通达信接口是一种用于获取、传输和处理股票市场相关数据的软件接口&#xff0c;以提供了一种连接股票市场数据源和数据使用者之间的通道&#xff0c;允许开发者通过编程方式获取股票行情数据、交易数据和相关信息等。如果调用通达信接口&#xff0c;需要借助以下几个方面的工具…

9-AJAX-1入门

AJAX 目录 AJAX 概念和 axios 使用认识 URLURL 查询参数常用请求方法和数据提交HTTP协议-报文接口文档案例 - 用户登录form-serialize 插件 01.AJAX 概念和 axios 使用 目标 了解 AJAX 概念并掌握 axios 库基本使用 讲解 什么是 AJAX ? mdn 使用浏览器的 XMLHttpRequest…

前后端分离------后端创建笔记(06)新增接口页面布局

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

[PyTorch][chapter 50][创建自己的数据集 2]

前言&#xff1a; 这里主要针对图像数据进行预处理.定义了一个 class Pokemon(Dataset) 类&#xff0c;实现 图像数据集加载,划分的基本方法. 目录&#xff1a; 整体框架 __init__ load_images save_csv divide_data __len__ denormalize __g…

[NepCTF 2023] crypto 复现

这个赛很不理想&#xff0c;啥都不会。 拿了WP看了几个题&#xff0c;记录一下 random_RSA 这题不会是正常情况&#xff0c;我认为。对于论文题&#xff0c;不知道就是不知道&#xff0c;基本没有可能自己去完成论文。 题目不长&#xff0c;只有两个菜单&#xff0c;共可交…

Springboot 在 redis 中使用 BloomFilter 布隆过滤器机制

一、导入SpringBoot依赖 在pom.xml文件中&#xff0c;引入Spring Boot和Redis相关依赖 <!-- Google Guava 使用google的guava布隆过滤器实现--><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><vers…

IPv4分组

4.3.1 IPv4分组 IP协议定义数据传送的基本单元——IP分组及其确切的数据格式 1. IPv4分组的格式 IPv4分组由首部和数据部分&#xff08;TCP、UDP段&#xff09;组成&#xff0c;其中首部分为固定部分&#xff08;20字节&#xff09;和可选字段&#xff08;长度可变&#xff0…

行业追踪,2023-08-14

自动复盘 2023-08-14 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

深入浅出 栈和队列(附加循环队列、双端队列)

栈和队列 一、栈 概念与特性二、Stack 集合类及模拟实现1、Java集合中的 Stack2、Stack 模拟实现 三、栈、虚拟机栈、栈帧有什么区别&#xff1f;四、队列 概念与特性五、Queue集合类及模拟实现1、Queue的底层结构&#xff08;1&#xff09;顺序结构&#xff08;2&#xff09;链…

做海外游戏推广有哪些条件?

做海外游戏推广需要充分准备和一系列条件的支持。以下是一些关键条件&#xff1a; 市场调研和策略制定&#xff1a;了解目标市场的文化、玩家偏好、竞争格局等是必要的。根据调研结果制定适合的推广策略。 本地化&#xff1a;将游戏内容、界面、语言、货币等进行本地化&#…

计算两个字符串之间的编辑距离【支持多字节字符串】

/*** 计算两个字符串之间的编辑距离【支持多字节字符串】** param string $str1 求编辑距离中的其中一个字符串* param string $str2 求编辑距离中的另一个字符串** return int*/ function levenshtein_copy(string $str1, string $str2): int {$arr1 mb_str_split($str1);$ar…

IK分词器升级,MySQL热更新助一臂之力

ik分词器采用MySQL热更新 ​ 官方所给的IK分词器只支持远程文本文件热更新&#xff0c;不支持采用MySQL热更新&#xff0c;没关系&#xff0c;这难不倒伟大的博主&#xff0c;给哈哈哈。今天就来和大家讲一下如何采用MySQL做热更新IK分词器的词库。 一、建立数据库表 CREATE…

20个常考的前端算法题,你全都会吗?

现在面试中&#xff0c;算法出现的频率越来越高了&#xff0c;大厂基本必考 今天给大家带来20个常见的前端算法题&#xff0c;重要的地方已添加注释&#xff0c;如有不正确的地方&#xff0c;欢迎多多指正&#x1f495; 1、两数之和 题目&#xff1a;给定一个数组 nums 和一…

d3dcompiler43.dll缺失怎么修复?dll缺失解决方法分享

在使用电脑过程中&#xff0c;我们有时会遇到一些系统文件的问题&#xff0c;其中一个常见的问题是d3dcompiler43.dll文件的损坏或丢失。当这个文件出现问题时&#xff0c;可能会导致应用程序无法正常运行或图形渲染出现异常。最近我也遇到了这个问题&#xff0c;以下是我修复d…

ClickHouse(十八):Clickhouse Integration系列表引擎

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &…

UE4拾取物品高亮显示

UE4系列文章目录 文章目录 UE4系列文章目录前言一、如何实现 前言 先看下效果&#xff0c;当角色靠近背包然后看向背包&#xff0c;背包就会高亮显示。 一、如何实现 1.为选中物品创建蓝图接口 在“内容” 窗口中&#xff0c;鼠标右键选择“蓝图”->蓝图接口&#xff0c…

P13-CNN学习1.3-ResNet(神之一手~)

论文地址:CVPR 2016 Open Access Repository https://arxiv.org/pdf/1512.03385.pdf Abstract 翻译 深层的神经网络越来越难以训练。我们提供了一个残差学习框架用来训练那些非常深的神经网络。我们重新定义了网络的学习方式&#xff0c;让网络可以直接学习输入信息与输出信息…

乐鑫ESP32S3串口下载出现奇怪问题解决方法

正在学习ESP32S3&#xff0c;有一个原厂BOX开发板&#xff0c;使用虚拟机&#xff0c;安装 debian11 &#xff0c;安装IDF4.4.5版本工具。下载box示例代码。 进入example,idf.py set-target esp32s3, idf.py flash 下载时&#xff0c;出现错误&#xff1a; Wrote 22224 bytes…

【Unity实战系列】如何把你的二次元老婆/老公导入Unity进行二创并且进行二次元渲染?(附模型网站分享)

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;在正式开始讲主线知识之前&#xff0c;我们先来讲点有趣且有用的东西。 我知道&#xff0c;除了很多想从事游戏开发行业的人以外&#xff0c;还…

试岗第一天问题

1、公司的一个项目拉下来 &#xff0c;npm i 不管用显示 后面百度 使用了一个方法 虽然解决 但是在增加别的依赖不行&#xff0c;后面发现是node版本过高&#xff0c;更换node版本解决。 2、使用插件动态的使数字从0到100&#xff08;vue-animate-number插件&#xff09; 第一…