2012-05-26 50 views
6

注:測試項目我提到可以下載:Spring DI applicationContext.xml xsi:schemaLocation究竟是如何使用的?

混帳克隆https://github.com/mperdikeas/so-spring-di-appcontext-schemalocation.git

..與「螞蟻運行」運行。

我'理解'XML名稱空間名稱只是用作不透明標識符,並不意味着用作URI(wikipedia)。我也'理解'XML模式位置是爲了提供關於模式文檔的實際位置的暗示,並且暗示,在實踐中不使用(w3.org)。考慮到這一點,我一直在試驗一個簡單的Spring DI應用程序(在簡單的J2SE設置中使用),方法是修改applicationContext.xml。這裏是開始版本:

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

當我做了「須藤使用ifconfig eth0的下降」項目完美地跑這與運行時沒有打擾來去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) 

這似乎表明,春季DI運行時使用的第二URL中的每一對在XSI :schemaLocation作爲某種標識符(由於沒有網絡訪問而在其邏輯中硬編碼)。所以我的假設是,Spring DI運行時爲每個名稱空間使用兩種標識符:唯一標識名稱空間(用作不透明字符串)的標識符和用於唯一標識該名稱空間的模式版本的標識符(用作不透明字符串)名稱空間(再次用作不透明字符串)。即實際上使用schemaLocation(以扭曲的方式?因爲這似乎不是w3c文檔的意圖)來對命名空間進行版本化。此外,在這種情況下,爲什麼Spring DI運行時不會抱怨「p」命名空間缺少模式位置。我的心智模式是否正確?

回答

10

這裏是發生了什麼:

  • XML模式允許你定義別名(短名稱),以XML命名空間。從技術上講,所有命名空間都由完整URI標識,但這會非常麻煩 - 所以您可以使用簡短的別名,如contextp。還有一個默認名稱空間xmlns屬性

  • 默認情況下,XML解析器假定名稱空間URI也是XSD文件的URL位置。這通常是這種情況,但不是規範要求的。如果不提供schemaLocation屬性,這也是Spring中XML解析器的工作原理。

  • schemaLocation用於從命名空間URI映射到XSD文件的物理位置(URL)。當架構名稱空間確實使用而不是指向有效的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 
+0

謝謝,這是一個清晰的模式。如果我可能還有兩個額外的問題:[1]在我的項目的庫中,只有一個spring.schemas文件(在spring.jar中),它似乎沒有包含像「xsi」描述的映射'p'命名空間(雖然我可以找到'上下文'和根名稱空間映射),[2]該映射的東西在哪裏記錄? –

+0

@MenelaosPerdikeas:不幸的是我不知道[1]和[2]的答案。 –