作为一个Spring资深老鸟,你是否也还不清楚xsi:schemaLocation的真正作用?
这一篇文章,告诉你所有的细节!
以下是,Spring XML的文件头配置信息,相信很多人对此已非常熟悉。
<?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">
</beans>
左右滑动查看完整代码
01
—
Schema-based Configuration
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
</project>
左右滑动查看完整代码
xmlns=“http://www.springframework.org/schema/beans”
左右滑动查看完整代码
prefix的作用:使用prefix可以区分不同xmlns中定义的相同属性值,不至于产生混乱。
举个例子,想必大家都有这样的经历:
班上出现了两个都叫张三的同学,平时为了区分,大家把其中一个同学叫大张三,另外一个同学叫小张三,这里的大和小,就像是两位张三同学拥有的prefix一样,有了这个prefix,相信班上所有与张三同学相关的事情,都清晰多了。
为什么xmlns的值看起来像一个URL
Namespace-name-URI仅表示一个字符串常量,它与是否要从网络上加载资源是没有任何关系的。
NameSpace讲究全局唯一,而URL(统一资源定位符)天生具备唯一性。
什么是xmlns:xsi
从前面我们知道,Spring XML遵循W3C XML Schema规范。
所以,引入此段文字就相当于声明了,当前XML文件符合W3C 规范。
换句话说,符合W3C规范的XML文件,都必须引入这段文字:
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”。
左右滑动查看完整代码
官方的意思是,写成xmlns:xsi只是大家的习惯而已。事实上,写成xmlns:xsixsi也是没有问题的。
为了达到认知上的统一,大家习惯性的写成xmlns:xsi而已。
02
—
XSD文件的合法性验证
XSD文件定义好之后,接下来一步就是验证文件的合法性。
即,确认该文件是否符合W3C XML Schema规范。
Spring使用Java自带的JAXP(JavaAPI for XML Processing)来解析验证XML。
除JAXP之外,还可以使用SAX或DOM来做相同的工作。
一起来看看,Spring的处理源码:
protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware)
throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(namespaceAware);
if (validationMode != XmlValidationModeDetector.VALIDATION_NONE) {
factory.setValidating(true);
if (validationMode == XmlValidationModeDetector.VALIDATION_XSD) {
// Enforce namespace aware for XSD...
factory.setNamespaceAware(true);
try {
factory.setAttribute(SCHEMA_LANGUAGE_ATTRIBUTE, XSD_SCHEMA_LANGUAGE);
}
catch (IllegalArgumentException ex) {
ParserConfigurationException pcex = new ParserConfigurationException(
"Unable to validate using XSD: Your JAXP provider [" + factory +
"] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? " +
"Upgrade to Apache Xerces (or Java 1.5) for full XSD support.");
pcex.initCause(ex);
throw pcex;
}
}
}
return factory;
}
左右滑动查看完整代码
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
左右滑动查看完整代码
第二步:启用对XML文件的检验
factory.setValidating(true);
左右滑动查看完整代码
默认情况下,JAXP验证的不是XSD类型的文件,而是DTD类型的文件
第三步:强制启用XSD验证
1、设置namespaceAware=true; 默认情况下:false
factory.setNamespaceAware(true);
启用schemaLocation对Namespace的感知
2、设置下面两个固定值,
public class DefaultDocumentLoader implements DocumentLoader {
// 请搜索,DefaultDocumentLoader类查看
private static final String SCHEMA_LANGUAGE_ATTRIBUTE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
private static final String XSD_SCHEMA_LANGUAGE = "http://www.w3.org/2001/XMLSchema";
factory.setAttribute(SCHEMA_LANGUAGE_ATTRIBUTE,XSD_SCHEMA_LANGUAGE)
左右滑动查看完整代码 通过设置上述属性值,将XML文件的验证方式从DTD切换到XSD。 以下是setAttribute()方法的doc描述: 从doc描述中可以看出,正是通过这一步的设置,使得JAXP解析器可以处理,schemaLocation中定义的xsd文件集合。 至此,我们分析了XSD文件的验证逻辑,但未涉及XSD文件的加载过程,此部分内容将在下章节展开讲。
届时,我们将了解到,Dubbo利用Spring Schema扩展机制,加载dubbo.xsd文件的技术原理。
如果感觉文章不错,欢迎持续关注我哦!
以上内容均为原创,版权归作者所有,侵权必究