spring源码深度解析—容器的基本实现,你知多少?( 四 )


文章插图
 
我们来梳理下上述时序图的处理过程: 
(1)封装资源文件 。当进入XmlBeanDefinitionReader后首先对参数Resource使用EncodedResource类进行封装 
(2)获取输入流 。从Resource中获取对应的InputStream并构造InputSource 
(3)通过构造的InputSource实例和Resource实例继续调用函数doLoadBeanDefinitions , loadBeanDefinitions函数具体的实现过程: 

spring源码深度解析—容器的基本实现,你知多少?

文章插图
 
EncodedResource的作用是对资源文件的编码进行处理的 , 其中的主要逻辑体现在getReader()方法中 , 当设置了编码属性的时候Spring会使用相应的编码作为输入流的编码 , 在构造好了encodeResource对象后 , 再次转入了可复用方法loadBeanDefinitions(new EncodedResource(resource)) , 这个方法内部才是真正的数据准备阶段 , 代码如下:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { Document doc = doLoadDocument(inputSource, resource); return registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException ex) { throw ex; } catch (SAXParseException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex); } catch (SAXException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", ex); } catch (ParserConfigurationException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, ex); } catch (IOException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, ex); } catch (Throwable ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, ex); }}在上面冗长的代码中假如不考虑异常类代码 , 其实只做了三件事 
- 获取对XML文件的验证模式 
- 加载XML文件 , 并得到对应的Document 
- 根据返回的Document注册Bean信息 
5.3 获取XML的验证模式 
XML文件的验证模式保证了XML文件的正确性 , 而比较常用的验证模式有两种:DTD和XSD 
5.3.1 DTD和XSD区别 
DTD(Document Type Definition)即文档类型定义 , 是一种XML约束模式语言 , 是XML文件的验证机制 , 属于XML文件组成的一部分 。DTD是一种保证XML文档格式正确的有效方法 , 可以通过比较XML文档和DTD文件来看文档是否符合规范 , 元素和标签使用是否正确 。一个DTD文档包含:元素的定义规则 , 元素间关系的定义规则 , 元素可使用的属性 , 可使用的实体或符合规则 。 
使用DTD验证模式的时候需要在XML文件的头部声明 , 以下是在Spring中使用DTD声明方式的代码:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//Spring//DTD BEAN 2.0//EN" "http://www.Springframework.org/dtd/Spring-beans-2.0.dtd">而以Spring为例 , 具体的Spring-beans-2.0.dtd部分如下:
<!ELEMENT beans ( description?, (import | alias | bean)*)><!-- Default values for all bean definitions. Can be overridden at the "bean" level. See those attribute definitions for details.--><!ATTLIST beans default-lazy-init (true | false) "false"><!ATTLIST beans default-autowire (no | byName | byType | constructor | autodetect) "no"><!ATTLIST beans default-dependency-check (none | objects | simple | all) "none"><!ATTLIST beans default-init-method CDATA #IMPLIED><!ATTLIST beans default-destroy-method CDATA #IMPLIED><!ATTLIST beans default-merge (true | false) "false"><!-- Element containing informative text describing the purpose of the enclosing element. Always optional. Used primarily for user documentation of XML bean definition documents.--><!ELEMENT description (#PCDATA)><!-- Specifies an XML bean definition resource to import.--><!ELEMENT import EMPTY>XML Schema语言就是XSD(XML Schemas Definition) 。XML Schema描述了XML文档的结构 , 可以用一个指定的XML Schema来验证某个XML文档 , 以检查该XML文档是否符合其要求 , 文档设计者可以通过XML Schema指定一个XML文档所允许的结构和内容 , 并可据此检查一个XML文档是否是有效的 。 


推荐阅读