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://www.mzph.cn/news/580627.shtml

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

相关文章

MQTT - 笔记

1 Mosquitto 官网 https://mosquitto.org/ 2 Windows环境下安装配置Mosquitto服务及入门操作介绍 Windows环境下安装配置Mosquitto服务及入门操作介绍-CSDN博客 3 开源:MQTT安装与配置使用 【C++】开源:MQTT安装与配置使用_c++ mqtt-CSDN博客 4 一文搞懂Qt-MQTT开发

使用js编写一个函数判断所有数据类型的通用方法

一、typeof 在 JavaScript 里使用 typeof 来判断数据类型&#xff0c;只能区分基本类型&#xff0c;即 “number”&#xff0c;”string”&#xff0c;”undefined”&#xff0c;”boolean”&#xff0c;”object” 五种。 对于数组、对象来说&#xff0c;其关系错综复杂&…

LeetCode day31

LeetCode day31 被创新实践的机器学习大作业和数据库作业折磨力&#xff0c;临近期末&#xff0c;各种大作业以及ddl&#xff0c;搞的咱只能偶尔刷刷力扣&#xff0c;但是csdn就挺难去发布了,大家期末也好好复习过个好年啦&#xff0c;O(∩_∩)O 409. 最长回文串 给定一个包含…

Unity中Shader裁剪空间推导(在Shader中实现)

文章目录 前言一、在Shader中&#xff0c;手动把正交相机的坐标转化到裁剪空间1、我们在属性面板定义一个变量&#xff0c;用于传入摄像机的信息2、获取h、r、w、n、f3、获取OpenGL下的转化矩阵4、 获取DirectX下的转化矩阵5、手动将观察空间下的坐标转换到裁剪空间下6、这里为…

MR实战:统计总分与平均分

文章目录 一、实战概述二、提出任务三、完成任务&#xff08;一&#xff09;准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录 &#xff08;二&#xff09;实现步骤1、创建Maven项目2、添加相关依赖3、创建日志属性文件4、创建成绩映射器类5、创建成绩驱动器类6、启…

新手如何快速熟悉代码,写出东西(持续更新)

目录 第一章、最小编程任务的设想1.1&#xff09;程序员入门会遇到的问题1.2&#xff09;编程任务的设想 第二章、编程任务的练习2.1&#xff09;代码初级练习2.2&#xff09;项目中级练习2.3&#xff09;其他编程练习 第三章、其他任务练习3.1&#xff09;中间件使用3.2&#…

操作索引库-mapping属性

目录 一、mapping属性 二、总结 一、mapping属性 mapping是对索引库中文档的约束&#xff0c;常见的mapping属性包括&#xff1a; type&#xff1a;字段数据类型&#xff0c;常见的简单类型有&#xff1a; 字符串: text (可分词的文本)、keyword (精确值&#xff0c;例如:品…

JavaScript基础知识点总结:从零开始学习JavaScript(三)

如果大家感感兴趣也可以去看&#xff1a; &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 学习…

2024重新洗牌“IT界”,是谁给它的底气?

​在2023年下半年" IT界"最引发程序员关注的热点话题就是鸿蒙了。 就今年9月25日&#xff0c;从华为发布会宣布明年2024将推出HarmonyOS NEXT版本后&#xff0c;这意味着”鸿蒙不再与android兼容“。鸿蒙将与安卓、ios形成”三足鼎立“之势。 鸿蒙激起千层浪 12月…

Kibana操作ElasticSearch

1、索引操作 1.1、新增索引 a、创建索引默认配置 PUT /索引名称 b、创建索引指定字段类型 put /索引名称/_mapping/typeName {"properties":{"字段名":{"type":"类型", text keyword long short date integer object"index&quo…

2023安洵杯-秦岭防御军wp

reverse 感觉有点点简单## import base64 def ba64_decode(str1_1):mapp "4KBbSzwWClkZ2gsr1qAQu0FtxOm6/iVcJHPY9GNp7EaRoDf8UvIjnL5MydTX3eh"data_1 [0] * 4flag_1 [0] * 3for i in range(32, 127):for y in range(32, 127):for k in range(32, 127):flag_1[0]…

【RocketMQ笔记02】安装RocketMQ可视化工具rocketmq-dashboard

这篇文章&#xff0c;主要介绍如何安装RocketMQ可视化工具rocketmq-dashboard。 目录 一、RocketMQ可视化界面 1.1、下载rocketmq-dashboard 1.2、修改配置文件 1.3、打包工程 1.4、启动rocketmq-dashboard 一、RocketMQ可视化界面 1.1、下载rocketmq-dashboard rocketm…

TYPE C 接口知识

1、Type C 概述 Type-C口有4对TX/RX分线&#xff0c;2对USBD/D-&#xff0c;一对SBU&#xff0c;2个CC&#xff0c;另外还有4个VBUS和4个地线。 当Type-C接口仅用作传输DP信号时&#xff0c;则可利用4对TX/RX&#xff0c;从而实现4Lane传输&#xff0c;这种模式称为DPonly模式…

【Leetcode】重排链表、旋转链表、反转链表||

目录 &#x1f4a1;重排链表 题目描述 方法一&#xff1a; 方法二&#xff1a; &#x1f4a1;旋转链表 题目描述 方法&#xff1a; &#x1f4a1;反转链表|| 题目描述 方法&#xff1a; &#x1f4a1;总结 &#x1f4a1;重排链表 题目描述 给定一个单链表 L 的头节…

软件测试/测试开发丨Python 装饰器常见的报错信息、原因和解决方案

Python 装饰器简介 装饰器&#xff08;Decorator&#xff09;是 Python 非常实用的一个语法糖功能。装饰器本质是一种返回值也是函数的函数&#xff0c;可以称之为“函数的函数”。其目的是在不对现有函数进行修改的情况下&#xff0c;实现额外的功能。 在 Python 中&#xf…

C#学习笔记 - C#基础知识 - C#从入门到放弃 - C# 接口、抽象与密封

C# 入门基础知识 - C# 接口、抽象与密封 第10节 接口、抽象与密封10.1 接口的声明10.2 接口的实现和继承10.3 显式实现接口10.4 抽象类与抽象方法声明10.5 抽象方法(abstract)方法与虚方法(virtual)方法10.6 密封类与密封方法10.7 接口综合运用实践 更多C#基础知识点可查看&…

ueditor富文本编辑器中图片上传地址配置以及抓取远程图片地址的配置

一&#xff1a;图片上传保存地址配置 打开文件ueditor.php,找到imagePathFormat进行修改即可 一&#xff1a;远程抓取图片配置 打开文件ueditor.config.js,找到catchRemoteImageEnable&#xff0c;取消注释即可

2024年元旦节放假通知

致尊敬的客户以及全体同仁&#xff1a; 旧岁已展千重锦&#xff0c;新年再进百尺竿。在这辞旧迎新之际&#xff0c;易天光通信提前祝您元旦快乐&#xff01;生意兴隆&#xff0c;身体健康&#xff0c;万事如意&#xff01;根据国家法定假期的规定&#xff0c;并结合公司实际情…

使用pycharm虚拟环境和使用conda管理虚拟环境的区别

使用 PyCharm 虚拟环境和使用 Conda 管理虚拟环境有一些区别&#xff0c;主要涉及到环境的创建、依赖管理、跨平台性等方面。以下是一些关键区别&#xff1a; 创建环境&#xff1a; PyCharm 虚拟环境&#xff1a; PyCharm 使用其自己的虚拟环境管理器&#xff08;通常是 venv&a…

开源verilog模拟 iverilog verilator +gtkwave仿真及一点区别

开源的 iverilog verilator 和商业软件动不动几G几十G相比&#xff0c;体积小的几乎可以忽略不计。 两个都比较好用&#xff0c;各有优势。 iverilog兼容性好。 verilator速度快。 配上gtkwave 看波形&#xff0c;仿真工具基本就齐了。 说下基本用法 计数器 counter.v module…