Spring DI applicationContext.xml究竟是xsi:schemaLocation使用的? [英] Spring DI applicationContext.xml how exactly is xsi:schemaLocation used?

查看:143
本文介绍了Spring DI applicationContext.xml究竟是xsi:schemaLocation使用的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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/上下文
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.SoapATMTransportp:retries =$ {transport.retries}/>



当我做了一个'sudo ifconfig eth0 down'项目运行完美,这与运行时不一致,从而无法从schemaLocations获取任何内容。但是,当我通过在每个对中的第二个URL中添加一个简单的下划线来对schemaLocations进行调整时,我收到以下投诉:

  java] org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException:类路径资源[META-INF / spring / applicationContext.xml]的XML文档中的第10行无效;嵌套异常是org.xml.sax.SAXParseException; lineNumber:10; columnNumber:100; cvc-elt.1:找不到元素bean的声明。 
[java]在org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:194)
[java]在org.apache.tools.ant.taskdefs.Java.run( java.java:771)
[java]在org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:221)
[java]在org.apache.tools.ant。 taskdefs.Java.executeJava(Java.java:135)
[java]在org.apache.tools.ant.taskdefs.Java.execute(Java.java:108)
[java]在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]在java.lang.reflect.Method.invoke(Method.java :601)
[java]在org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
[java]在org.apache.tools.ant.Task.perform ( Task.java:348)
[java]在org.apache.tools.ant.Target.execute(Target.java:390)
[java]在org.apache.tools.ant.Target。 performTasks(Target.java:411)
[java]在org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
[java]在org.apache.tools.ant。 Project.executeTarget(Project.java:1368)
[java]在org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[java]在org.apache。 tools.ant.Project.executeTargets(Project.java:1251)
[java]在org.apache.tools.ant.Main.runBuild(Main.java:809)
[java]在org。 apache.tools.ant.Main.startAnt(Main.java:217)
[java]在org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
[java ]在org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

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

解决方案

发生这种情况:





如果您搜索项目库,您会发现几个文件名为 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


Note: the test project I'm mentioning can be downloaded with:

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

.. and run with 'ant run'.

I 'understand' that XML namespace names are just used as opaque identifiers and not meant to be used as URIs (wikipedia). I also 'understand' that the XML schema locations are meant to provide hints as to the actual location of schema documents and, being hints, not used in practice (w3.org). With that in mind I 've been experimenting with a simple Spring DI application (used in a simple J2SE setting) by modifying the applicationContext.xml. Here is the starting version:

<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}"/>                          

When I did a 'sudo ifconfig eth0 down' the project ran perfectly which is consistent with the runtime not bothering to fetch anything from the schemaLocations. However, when I mangled the schemaLocations by adding a simple underscore to the second URL in each pair I received the following complaint:

 [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)

Which seems to suggest that Spring DI runtime uses the second URL in each pair at the xsi:schemaLocation as some kind of identifier (hardcoded in its logic since there is no network access). So my assumption would be that the Spring DI runtime uses two kind of identifiers for each namespace: the xmlns identifier to uniquely identify the namespace (used as an opaque string) and the schemaLocation identifier to uniquely identify the schema version for that namespace (again used as an opaque string). I.e. the schemaLocation is actually used (in a contorted way ? as that doesn't seem to be the intention of the w3c documents) to version the namespace. Moreover, in such a case, why doesn't the Spring DI runtime complain about the lack of a schemaLocation for the "p" namespace. Is my mental model correct?

解决方案

Here is what happens:

  • XML schema allows you to define aliases (short names) to XML namespaces. Technically all namespaces are identified by full URI but that would be very cumbersome - so you can use short aliases like context and p. There is also a default namespace denoted by xmlns attribute

  • By default XML parsers assume namespace URI is also a XSD file URL location. This is often the case, but is not required by the spec. This is also how XML parser in Spring works if you don't provide schemaLocation attribute.

  • schemaLocation is used to map from namespace URI to XSD file physical location (URL). It is used when schema namespace does not point to valid XSD URL (see MSDN on schemaLocation).

  • Last but not least, Spring adds yet another layer that translates Internet URLs to local files on CLASSPATH. This way your application can start without Internet connection (or when springframework.org site is down).

If you search your project libraries you'll find several files named spring.schemas. These files contain lines similar to below (extract from the file found in spring-context.jar, I added alignment):

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使用的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆