微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

《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方法自定义命名空间进行解析。对于标签自定义标签的解析我们将在之后的笔记中说明。

原文地址:https://www.jb51.cc/xml/294543.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。