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中。

相关推荐
To_OC3 小时前
从一行入口代码啃透 NestJS:工厂模式、装饰器和依赖注入是怎么串起来的
后端·设计模式·nestjs
Python私教3 小时前
多个项目怎么安全合并?先适配,再切换
后端·python·架构
Python私教5 小时前
从表格到管理系统:别先写页面,先补齐权限、流程和审计
数据库·后端·架构
北斗落凡尘5 小时前
LangGraph 入门实战(12)--使用MCP
后端·python·langchain
SomeB1oody7 小时前
【RustyML入门】6.0. 数学工具
开发语言·后端·机器学习·rust·教程
IT_陈寒7 小时前
为什么我的JavaScript闭包总是漏掉那个变量?
前端·人工智能·后端
用户8356290780518 小时前
如何使用 Python 将 PowerPoint 转换为 PDF 文档
后端·python
倔强的石头_8 小时前
从 8 行报错到一条故障链:我用蓝耘 MaaS 做了一个 AI 日志分析助手
后端
敲个大西瓜8 小时前
Spring Could Alibaba 核心面试题
java·后端·spring
用户8356290780518 小时前
如何使用 Python 为 PowerPoint 幻灯片添加切换效果
后端·python