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

相关推荐
一灯架构5 小时前
90%的人答错!一文带你彻底搞懂ArrayList
java·后端
mldong7 小时前
Python开发者狂喜!200+课时FastAPI全栈实战合集,10大模块持续更新中🔥
后端
GreenTea7 小时前
从 Claw-Code 看 AI 驱动的大型项目开发:2 人 + 10 个自治 Agent 如何产出 48K 行 Rust 代码
前端·人工智能·后端
Moment9 小时前
AI 全栈指南:NestJs 中的 Service Provider 和 Module
前端·后端·面试
IT_陈寒9 小时前
为什么我的JavaScript异步回调总是乱序执行?
前端·人工智能·后端
Moment10 小时前
AI全栈入门指南:NestJs 中的 DTO 和数据校验
前端·后端·面试
小村儿10 小时前
Harness Engineering:为什么你用 AI 越用越累?
前端·后端·ai编程
小码哥_常10 小时前
为什么PUT和DELETE请求在大公司中逐渐被弃用?
后端
宫_商_角_徵10 小时前
动态代理到底在做什么?
后端
苍何10 小时前
我把微信 cli 开源了,群消息终于不用爬楼了!
后端