Spring 系列之 Spring 源码笔记:容器的基本实现-中【三】

接上篇文章,链接: Spring 系列之 Spring 源码笔记:容器的基本实现-上【二】

4.2 加载 Bean

this.reader.loadBeanDefinitions(resource) 时序图:

XmlBeanFactory XmlBeanDefinitionReader EncodedResource Resource InputSource loadBeanDefinitions(resource) 1 new EncodedResource(resource) 2 encodedResource:EncodedResource 3 loadBeanDefinitions(encodedResource) 4 getResource() 5 resource:Resource 6 getInputStream() 7 inputStream:InputStream 8 new InputSource(inputStream) 9 inputSource:InputSource 10 doLoadBeanDefinitions(inputSource, encodedResource.getResource()) 11 loadedBeanDefinitionNum:int 12 loadedBeanDefinitionNum:int 13 loadedBeanDefinitionNum:int 14 XmlBeanFactory XmlBeanDefinitionReader EncodedResource Resource InputSource

从时序图梳理处理过程如下

  1. 封装资源文件。当进入 XmlBeanDefinitionReader 后首先对参数 Resource 使用 EncodedResource 类进行封装。
  2. 获取输入流。从 Resource 中获取对应的 InputStream 并构造 InputSource。
  3. 通过构造的 InputSource 实例和 Resource 实例继续调用函数 doLoadBeanDefinitions。

下面是 loadBeanDefinitions 函数具体的实现过程:
在这里插入图片描述
在这里插入图片描述上面的方法构造了一个有编码的 InputStreamReader。当构造好 encodedResource 对象后,再次转入了重载函数 loadBeanDefinitions,这个方法才是真正的数据准备阶段,也是时序图所描述的逻辑:
在这里插入图片描述再次整理数据准备阶段的逻辑:

  1. 首先对传入的 resource 参数做封装,目的是考虑到 Resource 可能存在编码要求的情况;
  2. 通过 SAX 读取 XML 文件的方式来准备 InputSource 对象;
  3. 将准备的数据传入真正的核心处理部分 doLoadBeanDefinitions(inputSource, encodedResource.getResource())

核心处理部分代码如下图所示:
在这里插入图片描述doLoadBeanDefinitions 函数其实只是做了两件事:

  1. 首先利用 DocumentLoader 获取 Document(具体细节后面进行分析);
    在这里插入图片描述
  2. 根据返回的 Document 注册 Bean 信息,关于注册 Bean 信息就很复杂,后面会花大篇幅进行总结。

5. 获取 XML 的验证模式

XML 文件的验证模式主要用于保证 XML 文件的正确性,常用的验证模式主要有两种:DTD 和 XSD。

5.1 DTD 和 XSD 的区别

DTD(Document Type Definition)翻译一下就是文档类型定义,是一种 XML 约束模式语言,属于 XML 文件的一部分,可以通过 DTD 文件来查看 XML 文档的正确性。比如 Mybatis 的 xml 文档(如下图)。
在这里插入图片描述
XSD(XML Schemas Definition) 是 XML Schemas 语言,XML Schema 本身是 XML 文档,可以用一个指定的 XML Schema 来验证 XML 文档。比如 Spring 的配置文件:
在这里插入图片描述
使用 XSD 检验时,除了要声明名称空间外(xmlns=“http://www.springframework.org/schema/beans”),还必须指定该名称空间所对应的 XSD 文档的存储位置,通过 schemaLocation 属性来指定名称空间所对应的 XSD 文档的存储位置,它包含两个部分,一部分是名称空间的 URI,另一部分就是该名称空间所表示的 XSD 位置或 URL 地址(xsi:schemaLocation=“http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.2.xsd”)。

这里只是简单介绍下 XML 文件的验证模式,如果需要更深研究,可以进一步查阅相关资料。

5.2 验证模式的获取

通过之前的分析,得知 Spring 通过 getValidationModeForResource(resource)
方法来获取对应资源的验证模式:
在这里插入图片描述
通过注释继续看自动检测方法 detectValidationMode(resource) 的代码:
在这里插入图片描述
在该函数中将自动检测验证验证模式的工作委托给了专门处理类:XmlValidationModeDetector,通过调用 XmlValidationModeDetector 的 detectValidationMode 方法进行处理,代码如下:
在这里插入图片描述

Spring 用来检测验证模式的办法就是判断是否包含 DOCTYPE,如果包含就是DTD,否则就是XSD.

6. 获取 Document

获取验证模式后就可以加载 Document 了,和获取 XML 验证模式一样,对于文档读取 XmlBeanDefinitionReader 类没有自己实现,而是委托给了 DoucumentLoader 去执行,而 DocuemtLoader 是个接口,其实真正调用的是 DefaultDocumentLoader,解析代码如下:
在这里插入图片描述

通过 SAX 解析 XML 文档:

  1. 首先创建 DocumentBuilderFactory;
  2. 再通过 DocumentBuilderFactory 创建 DocumentBuilder;
  3. 最后通过 DocumentBuilder 解析 inputSource 来返回 Document 对象

其中第二步的参数中的 entityResolver 是通过函数 getEntityResolver() 获取的返回值传进来的,代码如下:
在这里插入图片描述

接下文:Spring 系列之 Spring 源码笔记:容器的基本实现-下【四】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值