注意:我要提到的测试项目可以通过以下方式下载:

git clone https://github.com/mperdikeas/so-spring-di-appcontext-schemalocation.git

..并以“ant run”运行。

我“了解”到XML namespace 名称仅用作不透明标识符,而无意用作URI(wikipedia)。我还“理解” 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运行时为每个 namespace 使用两种标识符: xmlns 标识符(用于唯一地标识 namespace )(用作不透明字符串)和 schemaLocation 标识符(用于唯一地标识该 namespace 的模式版本)命名空间(再次用作不透明字符串)。 IE。实际使用了 schemaLocation (以扭曲的方式,因为这似乎不是w3c文档的目的)来对 namespace 进行版本控制。
而且,在这种情况下,Spring DI运行时为什么不提示“ p ” namespace 缺少 schemaLocation 。我的心理模型正确吗?

最佳答案

这是发生了什么:

  • XML模式允许您定义XML namespace 的别名(简称)。从技术上讲,所有 namespace 都是由完整URI标识的,但这非常麻烦-因此您可以使用简短的别名,例如contextp。还有一个默认的命名空间,由xmlns属性
  • 表示
  • 默认情况下,XML解析器假定 namespace URI也是XSD文件URL位置。通常是这种情况,但规范并不需要。如果您不提供schemaLocation属性,这也是Spring中XML解析器的工作方式。
  • schemaLocation用于从 namespace URI映射到XSD文件的物理位置(URL)。当架构 namespace 而不是指向有效的XSD URL时使用(请参阅MSDN on schemaLocation )。
  • 最后但并非最不重要的一点,Spring添加了另一层,它将Internet URL转换为CLASSPATH上的本地文件。这样,您的应用程序可以在没有Internet连接的情况下(或当springframework.org网站关闭时)启动。

  • 如果您搜索项目库,则会找到几个名为spring.schemas的文件。这些文件包含与下面类似的行(摘自spring-context.jar中找到的文件,我添加了对齐方式):
    http\://www.springframework.org/schema/context/spring-context.xsd= org/springframework/context/config/spring-context-3.1.xsd
    http\://www.springframework.org/schema/jee/spring-jee.xsd=         org/springframework/ejb/config/spring-jee-3.1.xsd
    http\://www.springframework.org/schema/lang/spring-lang.xsd=       org/springframework/scripting/config/spring-lang-3.1.xsd
    http\://www.springframework.org/schema/cache/spring-cache.xsd=     org/springframework/cache/config/spring-cache-3.1.xsd
    

    关于Spring DI applicationContext.xml xsi :schemaLocation used?到底是什么,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10768873/

    10-11 06:32