注意:我提到的测试项目可以通过以下方式下载:
git 克隆 https://github.com/mperdikeas/so-spring-di-appcontext-schemalocation.git
..并使用“ant run”运行。
我“理解”XML 命名空间名称只是用作不透明的标识符,而不是用作 URI(维基百科)。我还“理解”XML 模式位置旨在提供有关模式文档实际位置的提示,并且作为提示,在实践中未使用 ( w3.org )。考虑到这一点,我一直在通过修改 applicationContext.xml 来试验一个简单的 Spring DI 应用程序(用于简单的 J2SE 设置)。这是起始版本:
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:context = "http://www.springframework.org/schema/context"
xmlns:p = "http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="atm"/>
<context:property-placeholder location="classpath:META-INF/spring/atm.properties"/>
<bean id="soapTransport_" class="atm.SoapATMTransport" p:retries="${transport.retries}"/>
当我执行“sudo ifconfig eth0 down”时,项目运行完美,这与运行时一致,无需费心从 schemaLocations 中获取任何内容。但是,当我通过在每对中的第二个 URL 中添加一个简单的下划线来破坏 schemaLocations 时,我收到了以下投诉:
[java] org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 10 in XML document from class path resource [META-INF/spring/applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 10; columnNumber: 100; cvc-elt.1: Cannot find the declaration of element 'beans'.
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:194)
[java] at org.apache.tools.ant.taskdefs.Java.run(Java.java:771)
[java] at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:221)
[java] at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:135)
[java] at org.apache.tools.ant.taskdefs.Java.execute(Java.java:108)
[java] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[java] at java.lang.reflect.Method.invoke(Method.java:601)
[java] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
[java] at org.apache.tools.ant.Task.perform(Task.java:348)
[java] at org.apache.tools.ant.Target.execute(Target.java:390)
[java] at org.apache.tools.ant.Target.performTasks(Target.java:411)
[java] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
[java] at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
[java] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[java] at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
[java] at org.apache.tools.ant.Main.runBuild(Main.java:809)
[java] at org.apache.tools.ant.Main.startAnt(Main.java:217)
[java] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
[java] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
这似乎表明 Spring DI 运行时使用 xsi:schemaLocation 中每对中的第二个 URL 作为某种标识符(在其逻辑中硬编码,因为没有网络访问)。所以我的假设是 Spring DI 运行时对每个命名空间使用两种标识符:用于唯一标识命名空间的xmlns标识符(用作不透明字符串)和用于唯一标识该命名空间的架构版本的schemaLocation标识符(再次使用作为一个不透明的字符串)。即,schemaLocation实际上被使用(以一种扭曲的方式?因为这似乎不是 w3c 文档的意图)来对命名空间进行版本控制。而且,在这种情况下,为什么 Spring DI 运行时不抱怨缺少“ p ”命名空间的schemaLocation 。我的心智模型正确吗?