要深入瞭解Spring機制,首先需要知道Spring是怎樣在IoC容器中裝配Bean的。而瞭解這一點的前提是,要搞清楚Spring基於Schema的Xml配置方案。

在深入瞭解之前,必須要先明白幾個標籤的意思(我會逐步引導讀者理解,剛開始的懵懂無所謂,讀者自會漸入佳境。初極狹,才通人。復行數十步,豁然開朗。)。

  1. 什麼是XML Schema?

  用來描述 XML文件的結構,也被簡稱為XSD(XML Schema Definition),是一些規則的集合。(方式:通過定義schema檔案 如 spring-tx-3.0.xsd)

  2. xmlns?

  名稱空間是W3C推薦標準提供的一種統一命名XML文件中的元素和屬性的機制。

  3.xsd檔案?

  使用XML w3c 標準名稱空間中規定的元素和屬性編寫的以targetNamespace作為{目標名稱空間}的XML檔案,能夠約束引入此{目標名稱空間}定義的元素和屬性的XML檔案。

  4.targetNamespace?

  目標名稱空間,它的主要作用是指明Schema定義的元素的名稱空間。

親,是不是蒙圈了?我舉個栗子你感受一下,下面是一個note.xsd檔案示例:

程式碼001 

1 <?xml version="1.0"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn">
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

這個xsd檔案你就認為它是個有約束力的檔案,它將約束後面定義的與bean相關的xml,

第3行的xmlns就是一個統一的規則,它就是"法",平民百姓可以自由支配自己,但必須遵循這個"法"的管制。

5-14行就是約束的方法,第五行"<"後面的"xs"是這個約束的小名,對應著第3行"xmlns"後面的"xs",而約束檔案的全名就是第三行後面的以http開始的連結。(這個全名其實可以隨意定義,但是一般情況下用網站目錄來命名,一是便於區分,二是體現出本檔案在伺服器中的組織架構關係)。

第4行是本約束規則要約束哪個檔案?targetNamespace後面就是被約束檔案的大名。通緝令上寫上大名:抓捕漢奸王二麻子,然後捕頭就按圖索驥,尋找王二麻子這個人。下面是王二麻子:

程式碼002

1 <?xml version="1.0"?>
<note xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn
             http://www.w3school.com.cn /note.xsd">
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

看到木有,第2行xmlns後面,行不改名,坐不改姓,http://www.w3school.com.cn這就是這個配置檔案內定義的大名(代號王二麻子)。5到8行是這個bean配置檔案的屬性,這些屬性遵循的規則就是前面講到的程式碼001的5-14行約束。

這一行的xmlns後面本來也有個冒號+小名的,不寫表示預設名稱空間,spring中bean的定義都使用預設名稱空間。

那麼這個xmlns:xsi又是什麼呢?兄弟你記住一點,xmlns就是"法",它後面的東西都是定義的規則的大名和小名。

你看,程式碼001中第三行說明,規則的小名叫xs,規則的大名叫http://www.w3.org/2001/XMLSchema。

那麼,程式碼002中,xsi就是規則小名,後面的http://www.w3.org/2001/XMLSchema-instance就是規則的大名了。(跟程式碼001不同的是,001是自定義的,而xsi是spring原配的。)

第4行是呼叫xsi規則的schemaLocation子規則,這個規則是尋找具體約束它的檔案。(通過後面的連結就可以找到程式碼001這個檔案。)

與xmlns:xsi類似,spring內建了很多Schema約束檔案,如:beans、aop、tx、mvc、util等等,不一而足。

有了上面的栗子,spring專案裡具體的xml檔案就有所瞭解了,再來看,下面是一個小栗子的配置檔案:

程式碼003

1 <?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:p="http://www.springframework.org/schema/p"
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/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- 掃描類包,將標註Spring註解的類自動轉化Bean,同時完成Bean的注入 -->
<context:component-scan base-package="com.baobaotao.dao"/>
<context:component-scan base-package="com.baobaotao.service"/> <!-- 配置資料來源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/sampledb"
p:username="root"
p:password="2009118293zjl" /> <!-- 配置Jdbc模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="dataSource" /> <!-- 配置事務管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" /> <!-- 通過AOP配置提供事務增強,讓service包下所有Bean的所有方法擁有事務 -->
<aop:config proxy-target-class="true">
<aop:pointcut id="serviceMethod"
expression=" execution(* com.baobaotao.service..*(..))" />
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
</beans>

程式碼003中,3-7行都是spring的內建xsd,8-15行是呼叫xsi的schemaLocation去尋找具體的xsd位置。18-48行都是為各個規則定義了一些約束物件,王二麻子一籮筐。

如果你的電腦連了網,在myeclipse中開啟這個xml的時候,你可以隨便挑一個規則,滑鼠指在後面的連結上,按住ctrl鍵,點選連結,比如點選http://www.springframework.org/schema/tx/spring-tx-3.0.xsd這個連結,它會直接從內建瀏覽器通過訪問連結開啟這個xsd檔案,下面是開啟後的部分程式碼:

 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
- <xsd:schema xmlns="http://www.springframework.org/schema/tx" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tool="http://www.springframework.org/schema/tool" targetNamespace="http://www.springframework.org/schema/tx" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" />
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.0.xsd" />
- <xsd:annotation>
- <xsd:documentation>
- <![CDATA[
Defines the elements used in the Spring Framework's declarative
transaction management infrastructure. ]]>
</xsd:documentation>
</xsd:annotation>
- <xsd:element name="advice">

這個就是tx約束檔案,讀者可以大概看一下前面幾行的意思,這裡不做詳解。

但是有個問題,一般情況下開發專案怎麼可能保證聯網呢?不聯網的情況下這些約束如何生效?

其實,spring的jar包中都放了這些xsd檔案。比如用壓縮工具開啟org.springframework.beans-3.0.5.RELEASE.jar這個jar包,

這裡面都有。

Spring除了基於XML的配置,還有基於Bean,基於註解的配置。但是基於XML的配置功能最強,是基礎,是必須首先要了解的。

天道酬勤。共勉。