一直以來,寫Spring配置文件,都是把其餘配置文件的頭拷貝過來,最多改改版本號,也不清楚哪些是須要的,究竟是幹嗎的。今天整理一下,拒絕再無腦copy。java
<?xml version="1.0" encoding="UTF-8"?> <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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!--中間是配置文件部分--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="find*" propagation="NOT_SUPPORTED" /> </tx:attributes> </tx:advice> <aop:config> <aop:aspect id="***" ref="***"/> <aop:pointcut id="***" expression="****" /> </aop:config> <!--中間是配置文件部分--> </beans>
重點關注配置文件頭部分,就是寫在<beans >元素裏的部分。是否是感受到熟悉又陌生? 仔細瞭解後,不會再那麼神祕了。spring
XML 命名空間 是由國際化資源標識符 (IRI) 標識的 XML 元素和屬性集合;該集合一般稱做 XML「詞彙」。在XML中,元素名稱是由開發者定義的,當兩個不一樣的文檔使用相同的元素名時,就會發生命名衝突。舉個簡單的栗子,命名空間很像 Java 中的包,不一樣的包下面能夠存放相同的類名,只要在引入類時前面加上類的包就能夠避免同名類的衝突。express
命名空間被聲明爲元素的屬性。並不必定只在根元素聲明命名空間;而是能夠在 XML 文檔中的任何元素中進行聲明。聲明的命名空間的範圍起始於聲明該命名空間的元素,並應用於該元素的全部內容,直到被具備相同前綴名稱的其餘命名空間聲明覆蓋,其中,元素內容是指該元素的 <opening-tag> 和 </closing-tag> 之間的內容。編程
例如:上面的命名空間是在 <beans> </beans>元素中聲明的,全部其中聲明的命名空間在這兩個標籤中有效。windows
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:相似於一個保留字,它只用於聲明命名空間。換言之,xmlns 用於綁定命名空間,但其自己並不綁定到任何命名空間。eclipse
aop:這裏其實是將前綴「aop」與命名空間"http://www.springframework.org/schema/aop"(這個URI包含關於命名空間的信息)綁定在一塊兒。一般咱們會用一個比較簡短或約定俗成的名字來做爲命名空間的前綴(例如這裏的aop),但具體使用什麼前綴徹底取決於我的.自定義命名空間的前綴是合法的。使用有意義的命名空間前綴加強了XML檔的清晰性。因此能夠看到咱們平時在配置Spring配置文件的時候,前綴名都是aop(切面)、tx(事務)等命名方式。工具
配置了前綴後,咱們使用命名空間前綴以下:
spa
<aop:config> <aop:aspect id="***" ref="***"/> <aop:pointcut id="***" expression="****" /> </aop:config>
這裏咱們在配置面向切面編程的內容時,使用aop前綴,表明後面的元素(config,aspect等)都是在http://www.springframework.org/schema/aop中定義的。請注意,前綴只用做佔位符,而且必須經過能夠識別命名空間的 XML 分析器進行解釋才能使用綁定到該前綴的實際命名空間。code
單個默認命名空間xml
咱們看到,在配置文件中,beans,bean等元素咱們是沒有使用命名空間前綴的。重複限定一個要在命名空間中使用的元素或屬性可能會很是麻煩。
這種狀況下,能夠聲明一個 默認命名空間。不管在任什麼時候候都只能存在一個默認命名空間。
聲明一個 默認命名空間 意味着,若是 默認命名空間 聲明範圍內的任何元素未使用前綴顯式限定,則該元素將被隱式限定。與帶前綴的命名空間同樣,
默認命名空間 也能夠被覆蓋。
默認命名空間聲明方式以下:
xmlns="http://www.springframework.org/schema/beans"
也就是說,在命名空間範圍內,不帶有前綴的元素都是在這個命名空間內的,例如這裏的<beans> <bean>等,由於比較經常使用因此就讓
聲明他們的命名空間爲默認的啦,不用每次寫都帶前綴。
spring 整合了各類工具,而且spring提供了對各類工具的xml scheme 的配置方式,簡化了開發。對於各類工具的xml命名空間的引入,咱們也應該有一個比較清楚的認識。Spring在啓動時是要檢驗XML文件的。若是xml空間存在命名空間內沒有的元素是要報錯的。一般狀況下,命名空間對應的URI是一個存放XSD的地址,儘管規範沒有這麼要求。若是沒有提供schemaLocation,那麼Spring的XML解析器會從命名空間的URI里加載XSD文件。
例如咱們能夠這樣寫:
xmlns="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
則默認的命名空間就是加載指定的xsd文件。
schemaLocation提供了一個xml 命名空間到對應的XSD(Xml Schema Definition)文件的一個映射,它的值由一個或多個URI引用對組成,
兩個URI之間以空白符分隔(空格和換行都可)。第一個URI是定義的 XML命名空間的值,第二個URI給出Schema文檔的實際位置,
Schema處理器將從這個位置讀取Schema文檔,該文檔的targetNamespace必須與第一個URI(XML命名空間的值)相匹配。
這裏的注意與下面aop的命名空間URI位置對比一下。
在xsi:schemaLocation後面配置的字符串都是成對的,前面的是命名空間的URI,後面是xsd文件的URI;
好比咱們給出的例子(注意這裏已經用了一個命名前綴:xsi,這個xsi是在xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 聲明的):
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
這裏命名空間aop的值是「http://www.springframework.org/schema/aop」,它對應的xsd文件的位置爲「http://www.springframework.org/schema/aop/spring-aop-3.0.xsd」
咱們打開http://www.springframework.org/schema/aop/spring-aop-3.0.xsd,能夠看到xsd文件中targetNamespace的值和命名空間的值同樣。以下:
Spring默認在啓動時是要從配置的命名空間的位置加載XSD文件來驗證xml文件的,因此若是有的時候斷網了,或者一些開源軟件切換域名,那麼就很容易碰到應用啓動不了。
爲了防止這種狀況,Spring提供了一種機制,即默認從本地加載XSD文件,當本地沒有時才根據實際的URI去聯網得到。
咱們打開Spring-aop-4.1.6RELEASE.jar (這是我本地的版本),這個包下有一個META_INF文件夾,其中有兩個文件:spring.handlers和spring.schemas。
spring.handlers
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
spring.schemas
http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.2.xsd=org/springframework/aop/config/spring-aop-3.2.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.0.xsd=org/springframework/aop/config/spring-aop-4.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.1.xsd=org/springframework/aop/config/spring-aop-4.1.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.1.xsd
咱們看到一個xsd文件對應本地的一個路徑,咱們打開org/springframework/aop/config/能夠看到:
這就很明顯,Spring是把XSD文件放到本地了,再在spring.schemas裏作了一個映射,優先從本地裏加載XSD文件。
而且把spring舊版本的XSD文件也全放了。這樣能夠防止升級了Spring版本,而配置文件裏用的仍是舊版本的XSD文件,而後斷網了,應用啓動不了。
注意我在spring.schemas中標紅的最後一行,說明咱們在寫命名空間值對應的xsd文件位置時,能夠不用寫版本號,它默認的是本地spring相關版本的對應xsd版本,我這裏是4.1。
在xsi:schemaLocation中這樣寫:http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
對於spring配置文件的頭,已經有了一個比較清楚的認識。在之後寫配置文件的時候不會再一股腦得全拷貝過來。首先看看須要哪些功能,再導入相應的命名空間。
最好是在寫命名空間值對應的xsd文件位置的時候,不加版本號,讓spring加載本地版本對應的xsd文件。
固然,也可讓spring跳過對XML的校驗,具體方法:eclipse中,windows右鍵 ,去掉下圖紅色箭頭處的勾,就能夠對本工做空間取消驗證xml文件:
或者針對某個單獨的xml文件右鍵,validate也行。
針對已經驗證過的文件,並且也沒作修改。咱們能夠取消對其自動驗證。對於新建的配置文件,我以爲最好仍是不要取消驗證的好,畢竟咱們在配置文件的時候,有驗證會讓咱們今早發現錯誤。
補充,stackoverflow下的一個問題解答,很好的說明了 XML schema 命名空間如何與對應的class關聯起來的。也就是spring.handlers文件的做用。
http://stackoverflow.com/questions/11174286/spring-xml-namespaces-how-do-i-find-what-are-the-implementing-classes-behind-t
--總以爲本身講得不太清楚,還須要慢慢練習,多寫博客,鍛鍊表達寫做能力,文中有表達不清或有誤的地方歡迎留言指正討論。
---------------------------------
2017-3-29 Gonjan