首先,在我的这篇博客中已经说到容器是怎么初步实现的,并且要使用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:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd>

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

publicId:null

systemId:http://www.springframework.org/schema/beans/spring-beans.xsd

如果解析的验证模式是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"

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

publicId

Spring如何解析XML文件——Spring源码之XML初解析的更多相关文章

  1. 【vuejs深入二】vue源码解析之一,基础源码结构和htmlParse解析器

    写在前面 一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. vuejs是一个优秀的前端mvvm框架,它的易用性和渐进式的理念可以使每一个前端开发人员感到舒服,感到easy.它内 ...

  2. linux apache 不解析php文件显示源码

    首先检查是否安装PHP 没有的话就先安装 如果安装过 在/etc/httpd/conf/httpd.conf文件中 在<IfModule mime_module>里面 AddType ap ...

  3. spring MVC cors跨域实现源码解析

    # spring MVC cors跨域实现源码解析 > 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议.IP.http方法任意一个不同就 ...

  4. spring MVC cors跨域实现源码解析 CorsConfiguration UrlBasedCorsConfigurationSource

    spring MVC cors跨域实现源码解析 spring MVC cors跨域实现源码解析 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议 ...

  5. Spring PropertyResolver 占位符解析(二)源码分析

    Spring PropertyResolver 占位符解析(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) ...

  6. Spring Boot REST(二)源码分析

    Spring Boot REST(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) SpringBoot RE ...

  7. Spring 循环引用(二)源码分析

    Spring 循环引用(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环引用相关文章: & ...

  8. Spring第四天,BeanPostProcessor源码分析,彻底搞懂IOC注入及注解优先级问题!

  9. Spring系列28:@Transactional事务源码分析

    本文内容 @Transactional事务使用 @EnableTransactionManagement 详解 @Transactional事务属性的解析 TransactionInterceptor ...

  10. 涨姿势:Spring Boot 2.x 启动全过程源码分析

    目录 SpringApplication 实例 run 方法运行过程 总结 上篇<Spring Boot 2.x 启动全过程源码分析(一)入口类剖析>我们分析了 Spring Boot 入 ...

随机推荐

  1. javascript异步编程方案汇总剖析

    code[class*="language-"] { padding: .1em; border-radius: .3em; white-space: normal; backgr ...

  2. 用EL時(el-api.jar,el-ri.jar ),要設isELIgnored="false"

    用EL時(el-api.jar,el-ri.jar ),要設isELIgnored="false" 否则jstl标签不显示. 加上 <%@page isELIgnored="false ...

  3. php file_get_contents计时读取一个文件/页面 防止读取不到内容

    php file_get_contents计时读取一个文件/页面 防止读取不到内容 $url = 'http://www.baidu.com/index.php'; $opts = array( 'h ...

  4. 雷林鹏分享:C# 命名空间(Namespace)

    C# 命名空间(Namespace) 命名空间的设计目的是为了提供一种让一组名称与其他名称分隔开的方式.在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突. 定义命名空间 命名 ...

  5. Party CodeForces - 906C (状压)

    大意: 给定n(n<=22)个人, m个关系谁跟谁是朋友, 朋友关系是双向的, 每次操作可以选择一个人, 使他的朋友互相成为朋友, 求最少多少次操作可以使所有人互相认识 这个题挺巧妙的了, 关键 ...

  6. 『cs231n』绪论

    笔记链接 cs231n系列所有图片笔记均拷贝自网络,链接如上,特此声明,后篇不再重复. 计算机视觉历史 总结出视觉两个重要结论:1.基础的视觉神经识别的是简单的边缘&轮廓2.视觉是分层的 数据 ...

  7. view_countInfo

    create view view_countInfo as SELECT     a.dwmch, b.dwbh, b.djbh, c.rq, c.shl, c.djbh AS Expr1, d.sp ...

  8. oracle传入一个可能为空的参数进行查询

    在我们数据库的表中的某些字段可能为空,且传入的查询参数也可能为空. 例如 ,,); 其查询结果集如下 MAPPING_ID PARTY_ID VENDOR_ID SUPPLIER_REG_ID 332 ...

  9. Java容器涉及的类(代码)

    Customer: public class Customer implements Comparable{ private Integer customerId; private String cu ...

  10. 使用 PM2 管理nodejs进程

    pm2 是一个带有负载均衡功能的Node应用的进程管理器. 当你要把你的独立代码利用全部的服务器上的所有CPU,并保证进程永远都活着,0秒的重载, PM2是完美的. 它非常适合IaaS结构,但不要把它 ...