Spring DI applicationContext.xml究竟是如何使用xsi:schemaLocation的?

Mar*_*tus 9 spring dependency-injection applicationcontext

注意:我提到的测试项目可以下载:

git clone 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}"/>                          
Run Code Online (Sandbox Code Playgroud)

当我执行'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)
Run Code Online (Sandbox Code Playgroud)

这似乎表明Spring DI运行时使用xsi:schemaLocation中每对中的第二个URL作为某种标识符(由于没有网络访问,因此在其逻辑中硬编码).所以我的假设是Spring DI运行时为每个命名空间使用两种标识符:xmlns标识符用于唯一标识命名空间(用作不透明字符串)和schemaLocation标识符用于唯一标识该命名空间的模式版本(再次使用)作为一个不透明的字符串).即schemaLocation实际上是使用(以扭曲的方式?因为w3c文档的目的似乎不是)来命名空间.此外,在这种情况下,为什么Spring DI运行时没有抱怨缺少" p "命名空间的schemaLocation.我的心理模型是否正确?

Tom*_*icz 13

这是发生的事情:

  • XML模式允许您为XML名称空间定义别名(短名称).从技术上讲,所有名称空间都由完整的URI标识,但这将非常麻烦 - 因此您可以使用像context和的短别名p.还有一个由xmlnsattribute 表示的默认命名空间

  • 默认情况下,XML解析器假定命名空间URI也是XSD文件URL位置.通常情况如此,但规范并不要求.如果您不提供schemaLocation属性,这也是Spring中XML解析器的工作原理.

  • schemaLocation用于从名称空间URI映射到XSD文件物理位置(URL).当schema命名空间指向有效的XSD URL时使用它(请参阅MSDN onschemaLocation).

  • 最后但并非最不重要的是,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
Run Code Online (Sandbox Code Playgroud)