博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring如何解析XML文件——Spring源码之XML初解析
阅读量:5310 次
发布时间:2019-06-14

本文共 3570 字,大约阅读时间需要 11 分钟。

首先,在我的中已经说到容器是怎么初步实现的,并且要使用XmlBeanDefinitionReader对象对Xml文件进行解析,那么Xml文件是如何进行解析的,将在这片博客中进行一些陈述.


数据准备阶段

准备的目的是封装resource参数,目的是为了考虑到Resource可能存在编码要求的情况,其次,通过SAX读取XML文件的方式来准备InputSource对象,最后将参数传递到最核心的实现部分doLoadBeanDefinitions(inputSource,encodedResource.getResource())

封装Resource

调用XmlBeanDefinitionReaderloadBeanDefinitions(Resource resource)方法时,首先将resource对象进行再次封装成EncodedResource,查看源码可以发现里面增加了字符集和编码的封装,从命名上来看也可以体现出来,将资源封装完成后,就调用重载的同名函数loadBeanDefinitions(EncodedResource resource)进行正式的解析.

数据准备操作

在重载方法里面首先通过Set<EncodedResource> currentResources属性来记录已经加载的资源,其次,从EncodedResource对象中获取封装好的Resource对象,并获取其inputStream,将获取到的输入流与SAX解析的InputSource绑定,接下来就进入到了核心的实现部分:doLoadBeanDefinitions(inputSource,encodedResource.getResource())

核心实现

核心部分有两个关键步骤:

  1. 调用doLoadDocument(inputSource.resource)方法获取Document
  2. 根据返回的Document信息注册Bean信息

这两个步骤支持着整个Spring容器部分的实现基础

获取Document

进入方法体后,将Document的创建交给DefaultDocumentLoader documentLoader属性的loadDocument()方法,该方法声明如下:

Document loadDocument(            InputSource inputSource, EntityResolver entityResolver,            ErrorHandler errorHandler, int validationMode, boolean namespaceAware)            throws Exception;

调用情况:

documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,                getValidationModeForResource(resource), isNamespaceAware())
  • InputSource:SAX解析需要使用到的对象

  • EntityResolver:它的作用是项目本身就可以提供一个如何寻找DTD声明的方法,由程序来实现寻找DTD声明的过程,将DTD文件放到项目中某处,在实现时直接将此文档读取并返回给SAX即可,避免了必须通过网络来寻找相应的声明.

在这个接口中定义了一个方法

InputSource resolveEntity (String publicId,String systemId)        throws SAXException, IOException;

如果解析的验证模式是XSD:

那么.此时得到的两个参数值分别是:

publicId:null

systemId:

如果解析的验证模式是DTD:

那么,此时得到的两个参数值分别是:

publicId:-//Spring//DTD BEAN 2.0//EN

systemId:

而对于不同的验证模式,Spring使用了不同的解析器,当使用DTD验证时,Spring会截取后面的*.dtd,并直接到当前目录去寻找,当使用XSD验证时,Spring会到META-INF/Spring.schemas文件中去匹配相应的systemId并加载对应的XSD文件

  • validationMode:验证模式

首先,为了保证XML文件的正确性,有常见两种验证模式:DTDXSD

两种验证模式的区别

我对这两种的区别目前还不是很详细,只能简略的给出定义,但我看到的最直观的区别是,DTD验证需要单独写出一个标签<!DOCTYPE ...>,而XSD验证会将信息写入<beans xmlns="...">结点

DTD

DTD(Document Type Definition)即文档类型定义,是一种保证XML文档格式正确的有效方法,可以通过比较XML文档和DTD文件来看文档是否符合规范.

XSD

XML Schema语言就是XSD(XML Schema Definition),描述了XML文档的结构,可以用一个指定的XML Schema来验证XML文档,以检查文档是否符合要求.

验证模式的读取

验证模式的读取非常简单,在getValidationModeForResource(resource)方法中先获取当前设定的验证模式是不是自动选择,源码中是这么解释的since we cannot find a clear indication,当找不到一个确切的验证模式时,采用这种方式,然后判断当前resource对象中采用的是什么验证模式,通过检索字符串的方式,当存在DOCTYPE的时候,就采用DTD验证模式,否则采用XSD验证模式

  • namespaceAware:一个布尔值,默认为false,在前面可以看到,在使用XSD验证的时候会有xmlns="",其实就是XML namespace的缩写,可以有多个命名空间,如果使用的是XSD解析,将会把这个值改为true

解析并注册BeanDefinitions

在上一步得到Docment对象之后,调用registerBeanDefinitions(Document doc,Resource resource)

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {        //创建对象        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();        //记录当前已经加载的数量        int countBefore = getRegistry().getBeanDefinitionCount();        //加载并注册        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));        //返回本次加载的个数        return getRegistry().getBeanDefinitionCount() - countBefore;    }

而在调用documentReader对象方法中,才开始进行正式的解析工作

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {        this.readerContext = readerContext;        logger.debug("Loading bean definitions");        Element root = doc.getDocumentElement();        doRegisterBeanDefinitions(root);    }

解析的工作全权交给doRegisterBeanDefinition(root)方法实现,这样XML文件就正式进入了解析步骤,至于怎么解析的,博主将慢慢学习并写入后续博客.

转载于:https://www.cnblogs.com/yuanmiemie/p/6843586.html

你可能感兴趣的文章
C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
查看>>
jenkins搭建
查看>>
C#中使用Split分隔字符串的技巧
查看>>
eclipse的调试方法的简单介绍
查看>>
加固linux
查看>>
IPSP问题
查看>>
10.17动手动脑
查看>>
WPF中Image显示本地图片
查看>>
Windows Phone 7你不知道的8件事
查看>>
实用拜占庭容错算法PBFT
查看>>
java的二叉树树一层层输出,Java构造二叉树、树形结构先序遍历、中序遍历、后序遍历...
查看>>
php仿阿里巴巴,php实现的仿阿里巴巴实现同类产品翻页
查看>>
Node 中异常收集与监控
查看>>
七丶Python字典
查看>>
Excel-基本操作
查看>>
面对问题,如何去分析?(分析套路)
查看>>
Excel-逻辑函数
查看>>
面对问题,如何去分析?(日报问题)
查看>>
数据分析-业务知识
查看>>
nodejs vs python
查看>>