在使用XML Schema文档对XML实例文档进行检验 , 除了要声明名称空间外(xmlns=http://www.Springframework.org/schema/beans) , 还必须指定该名称空间所对应的XML Schema文档的存储位置 , 通过schemaLocation属性来指定名称空间所对应的XML Schema文档的存储位置 , 它包含两个部分 , 一部分是名称空间的URI , 另一部分就该名称空间所标识的XML Schema文件位置或URL地址(xsi:schemaLocation=”http://www.Springframework.org/schema/beanshttp://www.Springframework.org/schema/beans/Spring-beans.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"> <bean id="demo" class="com.yhl.myspring.demo.bean.MyBeanDemo"> <property name="beanName" value=https://www.isolves.com/it/cxkf/kj/"bean demo1"/> Spring-beans-4.3.xsd部分代码如下:

文章插图
5.3.2 验证模式的读取
在spring中 , 是通过getValidationModeForResource方法来获取对应资源的验证模式 , 其源码如下:
protected int getValidationModeForResource(Resource resource) { int validationModeToUse = getValidationMode(); if (validationModeToUse != VALIDATION_AUTO) { return validationModeToUse; } int detectedMode = detectValidationMode(resource); if (detectedMode != VALIDATION_AUTO) { return detectedMode; } // Hmm, we didn't get a clear indication... Let's assume XSD, // since apparently no DTD declaration has been found up until // detection stopped (before finding the document's root tag). return VALIDATION_XSD;}方法的实现还是很简单的 , 如果设定了验证模式则使用设定的验证模式(可以通过使用XmlBeanDefinitionReader中的setValidationMode方法进行设定) , 否则使用自动检测的方式 。而自动检测验证模式的功能是在函数detectValidationMode方法中 , 而在此方法中又将自动检测验证模式的工作委托给了专门处理类XmlValidationModeDetector的validationModeDetector方法 , 具体代码如下:
public int detectValidationMode(InputStream inputStream) throws IOException { // Peek into the file to look for DOCTYPE. BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); try { boolean isDtdValidated = false; String content; while ((content = reader.readLine()) != null) { content = consumeCommentTokens(content); if (this.inComment || !StringUtils.hasText(content)) { continue; } if (hasDoctype(content)) { isDtdValidated = true; break; } if (hasOpeningTag(content)) { // End of meaningful data... break; } } return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD); } catch (CharConversionException ex) { // Choked on some character encoding... // Leave the decision up to the caller. return VALIDATION_AUTO; } finally { reader.close(); } }Spring用来检测验证模式的办法就是判断是否包含DOCTYPE , 如果包含就是DTD , 否则就是XSD
5.4. 获取Document经过了验证模式准备的步骤就可以进行Document加载了 , 对于文档的读取委托给了DocumentLoader去执行 , 这里的DocumentLoader是个接口 , 而真正调用的是DefaultDocumentLoader , 解析代码如下:
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver, ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception { DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware); if (logger.isDebugEnabled()) { logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]"); } DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler); return builder.parse(inputSource);}分析代码 , 首选创建DocumentBuildFactory , 再通过DocumentBuilderFactory创建DocumentBuilder , 进而解析InputSource来返回Document对象 。对于参数entityResolver , 传入的是通过getEntityResolver()函数获取的返回值 , 代码如下:
protected EntityResolver getEntityResolver() { if (this.entityResolver == null) { // Determine default EntityResolver to use. ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader != null) { this.entityResolver = new ResourceEntityResolver(resourceLoader); } else { this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader()); } } return this.entityResolver;}
推荐阅读
- SpringBoot传输Long类型精度损失
- SpringMVC访问出错No converter found for return value of type
- 深度心理学,理解和超越自卑
- 赤霞珠、梅洛、黑皮诺、西拉......深度解读7大红葡萄品种
- 安卓|三星神速!基于Android 13深度定制的One UI 5.0已在路上
- 鲸鱼可以下潜10000米深吗 鲸鱼一般在海底多少米的深度
- 李沧区,促品牌化发展 深度培育放心茶 品牌茶
- 李剑叶:“飞扬”的设计将现代与传统深度融合
- Spring框架和Spring Boot框架的区别
- 茶 旅深度结合 黄山旅游品牌锦上添花
