Spring初级容器初始化:基础数据的准备

初探资源Resource加载的入口

XmlBeanFactory的构造方法中看下:

可以看到,下一步就是委托成员变量reader也就是XmlBeanDefinitionReader中的loadBeanDefinition来加载Resource资源了。

为了方便大家理解方法loadBeanDefinition的语义,在Spring容器中的每个bean的属性、普通方法、构造方法等bean相关的信息,都会封装在数据结构BeanDefinition中。

bean在最初注册到Spring容器时是以BeanDefinition的形式存在的,

EncodedResource是什么呢?

我们继续沿着loadBeanDefinitions方法,一步步来看下:

可以看到,在loadBeanDefinition方法中,首先将Resource资源封装为了EncodedResource,那EncodedResource有什么特别的地方呢?我们进去看下:

可以看到,在EncodedResource类中包含了三个成员变量,分别是Resource类型的resource,很明显resource就是用来存放我们传递进来的资源的。

最关键的就在于encoding和charset这两个成员变量,通过名称我们可以知道就是编码和字符集,加上EncodedResource的命名方式,我们可以推断出这个类就是在确定Resource资源的编码和字符集信息。

我们进入到EncodedResoruce的构造方法中来看下:

可以看到,EncodedResource的构造方法中,其实就是将resource对象设置到自己的成员变量resource中,同时还传了两个null值给到构造方法,也就是说encoding和charset默认值为null。

简单到EncodedResource类中看一下发现,使用到encoding和charset的也就是一个地方也就是getReader方法:

可以看到在getReader方法中,首先会通过getInputStream方法获取resource的输入流,同时会指定字符集或者编码来创建InputStreamReader。

但是,现在我们传入的charset和encoding都为null,所以创建的就是一个没有指定字符集和编码的InputStreamReader了。

InputStreamReader大家或多或少都了解过一点,就是Java SE IO流中将字节输入流转换为字符输入流的API,很明显接下来Spring将会以字符流的方式,读取我们的资源Resource。

基础数据的准备工作

了解完EncodedResource之后,我们再继续回到刚才的位置:

可以看到,将Resource资源封装为带字符集和编码类型的EncodedResource之后,现在继续调用XmlBeanDefinitionReader中的另外一个重载方法loadBeanDefinitions,我们进去看下:

前面的一些琐碎的代码,我们可以先跳过,可以看到首先会通过encodedResource调用getResource方法,获取我们刚才设置进去的Resource。

而前面我们通过Resource的类继承图可以知道,Resource是继承了InputStreamSource的,所以我们可以调用InputStreamSource中的getInputStream方法,获取Resource资源中的输入流,接下来,我们可以看到将输入流封装为了InputSource,然后再调用doLoadBeanDefinitions方法。

直到这一步,我们的数据准备工作才算完成了,从doLoadBeanDefinitions方法开始,我们就要正式开始解析xml配置文件了。

我们先一睹为快,看下doLoadBeanDefinitions方法里在干些什么事情:

可以看到,doLoadBeanDefinitions方法中大体来说就干了两件事,一是通过我们传进来的参数inputSource和resource创建xml文件的Document对象,另外就是解析Document对象将解析到的bean注入到Spring的容器中。

总结

XmlBeanDefinitionReader首先会将Resource封装为EncodedResource,EncodedResource相比于我们传进来的Resource只不过多了一些字符集和编码相关的设置,然后通过Resource中的输入流创建了InputSource,接下来进入到真正加载资源的方法doLoadBeanDefinitions中。

相关推荐
s91236010133 分钟前
【rust】 pub(crate) 的用法
开发语言·后端·rust
夕颜1112 小时前
关于排查问题的总结
后端
码事漫谈2 小时前
揭秘RAG的核心引擎:Document、Embedding与Retriever详解
后端
码事漫谈3 小时前
BM25 检索是什么
后端
Moment3 小时前
写代码也能享受?这款显示器让调试变得轻松又高效!😎😎😎
前端·后端
无双_Joney4 小时前
[更新迭代 - 1] Nestjs 在24年底更新了啥?(bug修复篇)
前端·后端·node.js
stark张宇5 小时前
从入门到放弃?一份让PHP学习持续正反馈的知识清单
后端·php
sunbin5 小时前
软件授权管理系统-整体业务流程图(优化版)
后端
一只专注做软件的湖南人5 小时前
京东商品评论接口(jingdong.ware.comment.get)技术解析:数据拉取与情感分析优化
前端·后端·api
TZOF5 小时前
TypeScript的新类型(二):unknown
前端·后端·typescript