《Spring源码深度解析》阅读笔记4-容器的基本实现之获取XML的验证模式、获取Document及解析及注册BeanDefinitons

获取XML的验证模式
配DTD与XSD的区别
DTD(Document Type Definition)即文档类型定义,是一种XML约束模式语言,是XML文件的验证机制,是属于XML文件组成的一部分。DTD是一种保证XML文档格式正确的有效方法,可以通过比较XML文档和DTD文件来看文档是否符合规范,元素和标签使用是否正确。一个DTD文档包含:元素的定义规则,元素间关系的定义规则,元素可使用的属性,可使用的属性或者实体规则。
要使用DTD验证模式的时候需要在XML文件的头部声明,以下是Spring中使用DTD声明方式的代码:

XML Schema语言就是XSD(XML Schema Definition)。XML Schema描述了XML文档的结构。可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其要求。文档设计者可以通过XML Schema指定一个XML文档所允许的结构和内容,并可据此检查一个XML文档是否有效。XML Schema本身就是一个XML文档,它符合XML语法结构。可以通过通用的XML解析器解析它。
在使用XML Schema文档对XML实例文档进行检验,除了要声明命名空间以外(xmlns=http://www.Springframework.org/schema/beans),还必须指定该命名空间所对应的XML Schema文档的储存位置。通过schemaLocation属性来指定命名空间所对应的XML Schema的存储位置,它包含两个部分:命名空间的URI和该命名空间所标识的XML Schema文件的存储位置或URL地址。
验证模式的读取
Spring中通过getValidationModeForResource方法来获取对应资源的验证模式。方法的实现比较简单,如果设定了验证模式则使用设定的验证模式(可以通过调用XmlBeanDefinitionReader中的setValidationMode方法进行设定),否则使用自动检测方式。而自动检测验证模式的功能在函数detectValidationMode方法中实现。

之后在函数 detectValidationMode中又将自动检测验证模式的工作委托给专门的处理类XmlValidationModeDetector,调用了XmlValidationModeDetector的validationModeDetector方法,在该方法中通过判断是否包含DOCTYPE来检测使用的验证模式,包含则是DTD模式,反之是XSD模式。

获取Document
经过了验证模式准备的步骤就可以进行Document加载了,同样XmlBeanFactoryReader类对文档读取并没有亲历亲为,而是委托给了DocumentLoader去执行,这里的DocumentLoader是个接口,真正调用的是DefaultDocumentLoader。

在loadDocument方法中涉及到一个参数EntityResolver,该参数的作用是提供一个如何寻找DTD声明的方法(默认通过网络来下载相应的DTD声明并进行认证。下载是一个漫长的过程,而且当网络中断或者不可用的时会报错),即由程序来实现寻找DTD声明的过程,比如我们将DTD文件放到项目中某处,在实现时直接将此文档读取并返回给SAX即可。这样就避免了通过网络来寻求相应的声明。

解析及注册BeanDefinitons
当把文档转换为Document后,接下来就是提取及注册bean。当程序已经拥有XMl文档文件的Document实例对象时,就会被引入下面这个方法。

这个方法中很好的应用了面向对象中单一职责的原则,将逻辑处理委托给单一的类进行处理,而这个逻辑处理类就是BeanDefinitonDocumentReader。BeanDefinitionDocumentReader是一个接口,而实例化的工作是在createBeanDefinitionDocumentReader()中完成的,而通过此方法BeanDefinitionDocumentReader真正的类型其实已经是DefaultBeanDefinitonDocumentReader了,进入DefaultBeanDefinitonDocumentReader后,发现这个方法的重要目的之一就是提取root,一遍再次将root作为参数继续BeanDefiniton的注册。


如果说以前一直是XML记载解析的准备阶段,那么RegisterBeanDefinitions算是真正的开始进行解析了。
profile属性的使用

我们注意到在注册Bean最开始是对PROFILE_ATTRIBUTE属性的解析,可能对我们来说profile属性并不是很常见。让我们先来了解一下这个属性。
分析profile之前我们先了解一下profile的用法,官方示例代码片段如下:

集成到Web环境中时,在web.xml中加入以下代码

有了这个特性我们就可以同时在配置文件中部署两套配置来适用于生产环境和开发环境,这样可以方便的进行切换开发、部署环境,最常用的就是更换不同的数据库。
在以上程序中会首先获取beans节点是否定义了profile属性,如果定义了则会需要到环境变量中去寻找,所以这里首先断言environment不可能为空,因为profile是可以同时指定多个的,需要程序对其拆分,并解析每个profile是否都符合环境变量中所定义的,不符合则不会浪费新能去解析。
解析并注册BeanDefinition
处理了profile之后就可以进行XML的读取了,跟踪代码进入parseBeanDefinitons(root, delegate)。

因为在Spring的XML配置文件里有两类差别非常大的Bean声明,一类是默认的,一类是自定义的。对于跟节点或者子节点是默认命名空间的话则采用parseDefaultElement方法进行解析,否则使用delegate.parseCustomElement方法对自定义命名空间进行解析。对于默认标签与自定义标签的解析我们将在之后的笔记中说明。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值