Spring实战系列(三)了解容器的基本实现

我们可以通过GitHub或者码云下载spring-framework源码,这边是基于5.X版本进行下载学习的。

地址:https://github.com/spring-projects/spring-framework

分析Spring源码是非常一件的难的事情,只能一步步学习,一步步记录。

       前面在第一章Spring整体架构中,bean是Spring中最核心的部分,在没有接触Spring的时候,我们使用bean是通过new 的方式进行创建,spring bean容器就是将这些对象交给spring去创建和管理,我们只需要在配置文件或者注解的方式告诉spring容器需要创建哪些bean对象。所以需要先在配置文件中定义好需要创建的bean对象,这些配置统称为bean定义配置元数据信息,spring容器通过读取这些bean配置元数据信息来构建和组装我们需要的对象,

我们通过一个入门案例来揭开Spring 容器是如何实现的

1.  创建一个简单的bean
public class TestBean {private String msg;public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}
2.  定义配置元数据信息,通过XML的方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="testBean" class="com.spring.demo.beans.TestBean"><property name="msg" value="put test bean msg"/></bean>
</beans>
3.   测试通过Spring获取bean
public class TestBeanMain {@Testpublic void testBeanLoad(){//在3.2版本以后不推荐使用 这里方便了解Spring内部原理// spring主要有2个容器,一个BeanFactory 一个ApplicationContext,后者是前者一个扩展容器BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("bean-config.xml"));TestBean testBean = (TestBean) xmlBeanFactory.getBean("testBean");System.out.println(testBean.getMsg());}
}

运行结果:

用于实现上面功能的是org.springframework.bean.jar
功能分析

     通过上面的一个简单案例,主要完成的功能步骤如下:

  • 读取配置文件bean-config.xml
  • 根据配置文件中的配置元信息找到对应类的配置,并进行反射实例化
  • 调用实例化的实例
源码分析
XmlBeanFactory对DefaultListableBeanFactory进行了扩展,主要用于从XML文档中读取BeanDefinition,注册和获取bean都是从父类通过继承的方式去实的。代码如下:

进入XmlBeanDefinitionReader类的loadBeanDefinitions方法,这是资源加载的真正实现。

	@Overridepublic int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {// 对资源文件进行编码处理return loadBeanDefinitions(new EncodedResource(resource));}
	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {// 资源不可为空验证Assert.notNull(encodedResource, "EncodedResource must not be null");if (logger.isTraceEnabled()) {logger.trace("Loading XML bean definitions from " + encodedResource);}// 通过属性来记录已经加载过的资源Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();// 添加失败抛出异常 当已存在if (!currentResources.add(encodedResource)) {throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");}//从encodedResource中获取已经封装好的resource资源并从中获取inputStreamtry (InputStream inputStream = encodedResource.getResource().getInputStream()) {InputSource inputSource = new InputSource(inputStream);if (encodedResource.getEncoding() != null) {// 设置编码inputSource.setEncoding(encodedResource.getEncoding());}//真正进入加载核心内容return doLoadBeanDefinitions(inputSource, encodedResource.getResource());}catch (IOException ex) {throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), ex);}finally {//加载完记录中移除currentResources.remove(encodedResource);if (currentResources.isEmpty()) {this.resourcesCurrentlyBeingLoaded.remove();}}}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)throws BeanDefinitionStoreException {try {// 获取XML文件的验证模式,对XML进行加载并得到对应的DocumentDocument doc = doLoadDocument(inputSource, resource);// 返回根据XML文件中注册bean的个数int count = registerBeanDefinitions(doc, resource);if (logger.isDebugEnabled()) {logger.debug("Loaded " + count + " bean definitions from " + resource);}return count;}//省略其他代码.......}

后续会对上面XML验证加载以及获取bean信息进行深入。

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

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

相关文章

【负载均衡oj】(四) 运行模块

一.目的 主要负责运行可执行程序。通过文件名就能运行程序。 二.runner run运行模块: 不需要关心运行结果是否正确&#xff0c;只具备基本运行功能并只关心是否运行出错。 一个程序的时候&#xff0c;有三种IO需要关心&#xff0c;标准错误&#xff0c;标准输出&#xff0c…

文献速递:人工智能医学影像分割---一个用于 COVID-19 CT 图像的粗细分割网络

01 文献速递介绍 如今&#xff0c;根据国家癌症研究所的报告&#xff0c;美国约有9.9%的男性患有前列腺癌。1 此外&#xff0c;根据美国癌症协会的数据&#xff0c;预计2019年将有174,650个新病例被诊断出前列腺癌&#xff0c;与此同时大约有31,620名男性将死于前列腺癌。因此…

百度CTO王海峰:文心一言用户规模破1亿

▶ 写在前面▶ 飞桨开发者已达1070万▶ 文心一言用户规模破亿&#xff0c;日提问量快速增长 ▶ 写在前面 “文心一言用户规模突破 1 亿。”12 月 28日&#xff0c;百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰在第十届 WAVE SUMMIT 深度学习开发者大会上宣布…

AtCoder Beginner Contest 334

B - Christmas Trees 分析&#xff1a; 讨论三种情况 1&#xff09; l<a<r 2&#xff09;a<l 3&#xff09;a>r 虽然简单&#xff0c;但是坑还是有一些的 例如2的策略是&#xff0c;[a,r]的树 - [a,l]的树&#xff0c;然后要注意 l 点有没有树&#xff0c;如…

要学习openfoam,c++需要掌握到什么程度?

要学习openfoam&#xff0c;c需要掌握到什么程度&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「c的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&…

2023年12月27日学习记录_加入噪声

目录 1、今日计划学习内容2、今日学习内容1、add noise to audio clipssignal to noise ratio(SNR)加入 additive white gaussian noise(AWGN)加入 real world noises 2、使用kaggel上的一个小demo&#xff1a;CNN模型运行时出现的问题调整采样率时出现bug 3、明确90dB下能否声…

从 Linux Crontab 到 K8s CronJob,定时任务正在经历怎样的变革

作者&#xff1a;黄晓萌(学仁) 背景 Job 表示短周期的作业&#xff0c;定时 Job 表示按照预定的时间运行Job&#xff0c;或者按照某一频率周期性的运行 Job。比如&#xff1a; 许多传统企业使用 Linux 自带的 crontab 来做定时任务的方案&#xff0c;该方案非常简单&#xff…

docker学习笔记02-安装mysql

1.安装mysql8 下载MySQL镜像 docker pull mysql:8.0创建并启动容器 docker run -itd --name mysqltest -p 9999:3306 -e MYSQL_ROOT_PASSWORD123456 mysql其中-it是交互界面 -d是后台执行 -name 指定容器名称 -p指定映射端口 -e设置环境变量 最后mysql是镜像名或者用镜像id如…

最新云渲染平台选择,云渲染避免踩坑指南

​随着云计算技术的飞速发展&#xff0c;云渲染逐步成为各类行业的优选工具&#xff0c;它凭借出色的效能和强大的并行计算能力&#xff0c;显著提高了工作效率&#xff0c;然而&#xff0c;要想充分利用云渲染技术&#xff0c;选择一款合适的云渲染平台是刻不容缓的课题&#…

一种删除 KubeSphere 中一直卡在 Terminating 的 Namespace--KubeSphere Logging System的简单方法

文章目录 一、问题提出二、删除方法1&#xff0c;获取kubesphere-logging-syste的详细信息json文件2&#xff0c;编辑kubesphere-logging-system.json3&#xff0c;执行清理命令 三、检查结果 一、问题提出 在使用 KubeSphere 的时候发现有一个日志服务KubeSphere Logging Sys…

React快速入门之交互性

响应事件 创建事件处理函数 处理函数名常以handle事件名命名 function handlePlayClick() {alert(Playing);}传递事件处理函数 函数名、匿名两种方式&#xff01; function PlayButton() {function handlePlayClick() {alert(Playing);}return (<Button handleClick{handl…

网站显示不安全警告怎么办?消除网站不安全警告超全指南

网站显示不安全警告怎么办&#xff1f;当用户访问你的网站&#xff0c;而您的网站没有部署SSL证书实现HTTPS加密时&#xff0c;网站就会显示不安全警告&#xff0c;这种警告&#xff0c;不仅有可能阻止用户继续浏览网站&#xff0c;影响网站声誉&#xff0c;还有可能影响网站在…

Android 8.1 设置USB传输文件模式(MTP)

项目需求&#xff0c;需要在电脑端adb发送通知手机端接收指令&#xff0c;将USB的仅充电模式更改成传输文件&#xff08;MTP&#xff09;模式&#xff0c;便捷用户在我的电脑里操作内存文件&#xff0c;下面是我们的常见的修改方式 1、android12以下、android21以上是这种方式…

纸质版表格怎么用扫描仪转换成电子版表格

要将纸质版表格转换成电子版表格&#xff0c;可以使用以下步骤&#xff1a; 1、准备一台物理扫描仪并与电脑连接好&#xff0c;并安装好驱动。 2、打开安装好的金鸣表格文字识别电脑客户端。 3、点击“扫描文件”&#xff0c;在弹出的对话框中选中需要使用的扫描仪。 4、点击“…

法线贴图可以实现什么样的3D效果

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 在 3D 建模中&#xff0c;曲面由多边形表示。照明计算是基于这些多边…

成考生必看!2023年成人高考录取后入学拿证流程

成人高考录取后并不是就可以坐等拿证了&#xff01; 成人高考录取后你还有这些事情要做。 一起来了解一下吧&#xff01; 成人高考入学到拿证流程 办理入学流程 1.入学时间 确认被高校录取后&#xff0c;12月下旬左右开始办理入学(实际时间以各院校安排为准&#xff09; 2.缴…

【28】Kotlin语法进阶——使用协程编写高效的并发程序

提示&#xff1a;此文章仅作为本人记录日常学习使用&#xff0c;若有存在错误或者不严谨得地方欢迎指正。 文章目录 一、Kotlin中的协程1.1 协程的基本用法1.1.1协程与协程作用域1.1.2 使用launch函数创建子协程1.1.3 通过suspend关键声明挂起函数1.1.4 coroutineScope函数 1.2…

Arduino串口测试

目录 一、硬件介绍 1、控制器 2、TTL转USB串口 二、软件程序 1、单片机发送字符串 &#xff08;1&#xff09;每个串口对应的类名称介绍 &#xff08;2&#xff09;发送功能 &#xff08;3&#xff09;代码 &#xff08;4&#xff09;测试 2、单片机接收字符串 &…

鸿蒙开发之android对比开发《基础知识》

基于华为鸿蒙未来可能不再兼容android应用&#xff0c;推出鸿蒙开发系列文档&#xff0c;帮助android开发人员快速上手鸿蒙应用开发。 1. 鸿蒙使用什么基础语言开发&#xff1f; ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript&#xff08;简称TS&#xff09;基本语法风…

记录 | ubuntu源码编译python3.7.3(指定版本)

一、安装依赖包 sudo apt-get install -y make build-essential libssl-dev zlib1g-dev sudo apt-get install -y libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm sudo apt-get install -y libncurses5-dev libncursesw5-dev xz-utils tk-dev 二、从Python网…