XML Schema

本附錄部分列出了與核心容器相關的 XML Schema。

util Schema

顧名思義,util 標籤用於處理常見的、工具性質的配置問題,例如配置集合、引用常量等。要使用 util Schema 中的標籤,您需要在 Spring XML 配置檔案頂部新增以下序言(程式碼段中的文字引用了正確的 Schema,以便 util 名稱空間中的標籤對您可用)

<?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:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">

		<!-- bean definitions here -->

</beans>

使用 <util:constant/>

考慮以下 Bean 定義

<bean id="..." class="...">
	<property name="isolation">
		<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
				class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
	</property>
</bean>

上述配置使用 Spring FactoryBean 實現(即 FieldRetrievingFactoryBean)將 Bean 的 isolation 屬性值設定為 java.sql.Connection.TRANSACTION_SERIALIZABLE 常量的值。這很好,但它比較冗長,並且(不必要地)向終端使用者暴露了 Spring 的內部實現細節。

以下基於 XML Schema 的版本則更簡潔,清晰地表達了開發者的意圖(“注入此常量值”),並且更易讀

<bean id="..." class="...">
	<property name="isolation">
		<util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
	</property>
</bean>

從欄位值設定 Bean 屬性或構造方法引數

FieldRetrievingFactoryBean 是一個 FactoryBean,用於檢索靜態或非靜態欄位值。它通常用於檢索 public static final 常量,然後這些常量可用於設定另一個 Bean 的屬性值或構造方法引數。

以下示例展示瞭如何透過使用 staticField 屬性來公開靜態欄位

<bean id="myField"
		class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
	<property name="staticField" value="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</bean>

還有一種便捷用法形式,其中靜態欄位被指定為 Bean 名稱,如下例所示

<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
		class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>

這意味著 Bean 的 id 不再有任何選擇(因此引用它的任何其他 Bean 也必須使用這個較長的名稱),但這種形式定義起來非常簡潔,並且作為內部 Bean 使用時非常方便,因為 Bean 引用無需指定 id,如下例所示

<bean id="..." class="...">
	<property name="isolation">
		<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
				class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
	</property>
</bean>

您還可以訪問另一個 Bean 的非靜態(例項)欄位,具體描述請參見 FieldRetrievingFactoryBean 類的 API 文件。

在 Spring 中,將列舉值注入到 Bean 中作為屬性或構造方法引數非常容易。您實際上不必做任何事情,也不必瞭解 Spring 的內部細節(甚至不必瞭解 FieldRetrievingFactoryBean 等類)。以下列舉示例展示了注入列舉值有多簡單

  • Java

  • Kotlin

package jakarta.persistence;

public enum PersistenceContextType {

	TRANSACTION,
	EXTENDED
}
package jakarta.persistence

enum class PersistenceContextType {

	TRANSACTION,
	EXTENDED
}

現在考慮以下 PersistenceContextType 型別的 setter 方法以及相應的 Bean 定義

  • Java

  • Kotlin

package example;

public class Client {

	private PersistenceContextType persistenceContextType;

	public void setPersistenceContextType(PersistenceContextType type) {
		this.persistenceContextType = type;
	}
}
package example

class Client {

	lateinit var persistenceContextType: PersistenceContextType
}
<bean class="example.Client">
	<property name="persistenceContextType" value="TRANSACTION"/>
</bean>

使用 <util:property-path/>

考慮以下示例

<!-- target bean to be referenced by name -->
<bean id="testBean" class="org.springframework.beans.TestBean" scope="prototype">
	<property name="age" value="10"/>
	<property name="spouse">
		<bean class="org.springframework.beans.TestBean">
			<property name="age" value="11"/>
		</bean>
	</property>
</bean>

<!-- results in 10, which is the value of property 'age' of bean 'testBean' -->
<bean id="testBean.age" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>

上述配置使用 Spring FactoryBean 實現(即 PropertyPathFactoryBean)建立一個名為 testBean.age 的 Bean(int 型別),其值等於 testBean Bean 的 age 屬性值。

現在考慮以下示例,它添加了一個 <util:property-path/> 元素

<!-- target bean to be referenced by name -->
<bean id="testBean" class="org.springframework.beans.TestBean" scope="prototype">
	<property name="age" value="10"/>
	<property name="spouse">
		<bean class="org.springframework.beans.TestBean">
			<property name="age" value="11"/>
		</bean>
	</property>
</bean>

<!-- results in 10, which is the value of property 'age' of bean 'testBean' -->
<util:property-path id="name" path="testBean.age"/>

<property-path/> 元素的 path 屬性值遵循 beanName.beanProperty 的形式。在此示例中,它獲取名為 testBean 的 Bean 的 age 屬性。該 age 屬性的值是 10

使用 <util:property-path/> 設定 Bean 屬性或構造方法引數

PropertyPathFactoryBean 是一個 FactoryBean,用於評估給定目標物件上的屬性路徑。目標物件可以直接指定或透過 Bean 名稱指定。然後您可以將此值用作另一個 Bean 定義中的屬性值或構造方法引數。

以下示例展示瞭如何透過名稱對另一個 Bean 使用路徑

<!-- target bean to be referenced by name -->
<bean id="person" class="org.springframework.beans.TestBean" scope="prototype">
	<property name="age" value="10"/>
	<property name="spouse">
		<bean class="org.springframework.beans.TestBean">
			<property name="age" value="11"/>
		</bean>
	</property>
</bean>

<!-- results in 11, which is the value of property 'spouse.age' of bean 'person' -->
<bean id="theAge"
		class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
	<property name="targetBeanName" value="person"/>
	<property name="propertyPath" value="spouse.age"/>
</bean>

在以下示例中,路徑針對內部 Bean 進行評估

<!-- results in 12, which is the value of property 'age' of the inner bean -->
<bean id="theAge"
		class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
	<property name="targetObject">
		<bean class="org.springframework.beans.TestBean">
			<property name="age" value="12"/>
		</bean>
	</property>
	<property name="propertyPath" value="age"/>
</bean>

還有一種快捷形式,其中 Bean 名稱就是屬性路徑。以下示例展示了這種快捷形式

<!-- results in 10, which is the value of property 'age' of bean 'person' -->
<bean id="person.age"
		class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>

這種形式確實意味著 Bean 的名稱沒有選擇。任何引用它的地方都必須使用相同的 id,即該路徑。如果用作內部 Bean,則根本無需引用它,如下例所示

<bean id="..." class="...">
	<property name="age">
		<bean id="person.age"
				class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
	</property>
</bean>

您可以在實際定義中明確設定結果型別。對於大多數用例來說這不是必需的,但有時會很有用。有關此功能的更多資訊,請參見 javadoc。

使用 <util:properties/>

考慮以下示例

<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<bean id="jdbcConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
	<property name="location" value="classpath:com/foo/jdbc-production.properties"/>
</bean>

上述配置使用 Spring FactoryBean 實現(即 PropertiesFactoryBean)例項化一個 java.util.Properties 例項,其值從提供的 資源 位置載入)。

以下示例使用 util:properties 元素來建立更簡潔的表示

<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<util:properties id="jdbcConfiguration" location="classpath:com/foo/jdbc-production.properties"/>

使用 <util:list/>

考慮以下示例

<!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' -->
<bean id="emails" class="org.springframework.beans.factory.config.ListFactoryBean">
	<property name="sourceList">
		<list>
			<value>[email protected]</value>
			<value>[email protected]</value>
			<value>[email protected]</value>
			<value>[email protected]</value>
		</list>
	</property>
</bean>

上述配置使用 Spring FactoryBean 實現(即 ListFactoryBean)建立一個 java.util.List 例項,並使用提供的 sourceList 中的值進行初始化。

以下示例使用一個 <util:list/> 元素來建立更簡潔的表示

<!-- creates a java.util.List instance with the supplied values -->
<util:list id="emails">
	<value>[email protected]</value>
	<value>[email protected]</value>
	<value>[email protected]</value>
	<value>[email protected]</value>
</util:list>

您還可以透過使用 <util:list/> 元素的 list-class 屬性,明確控制例項化和填充的 List 的確切型別。例如,如果我們確實需要例項化一個 java.util.LinkedList,可以使用以下配置

<util:list id="emails" list-class="java.util.LinkedList">
	<value>[email protected]</value>
	<value>[email protected]</value>
	<value>[email protected]</value>
	<value>d'[email protected]</value>
</util:list>

如果未提供 list-class 屬性,容器將選擇一個 List 實現。

使用 <util:map/>

考慮以下示例

<!-- creates a java.util.Map instance with values loaded from the supplied 'sourceMap' -->
<bean id="emails" class="org.springframework.beans.factory.config.MapFactoryBean">
	<property name="sourceMap">
		<map>
			<entry key="pechorin" value="[email protected]"/>
			<entry key="raskolnikov" value="[email protected]"/>
			<entry key="stavrogin" value="[email protected]"/>
			<entry key="porfiry" value="[email protected]"/>
		</map>
	</property>
</bean>

上述配置使用 Spring FactoryBean 實現(即 MapFactoryBean)建立一個 java.util.Map 例項,並使用提供的 'sourceMap' 中的鍵值對進行初始化。

以下示例使用一個 <util:map/> 元素來建立更簡潔的表示

<!-- creates a java.util.Map instance with the supplied key-value pairs -->
<util:map id="emails">
	<entry key="pechorin" value="[email protected]"/>
	<entry key="raskolnikov" value="[email protected]"/>
	<entry key="stavrogin" value="[email protected]"/>
	<entry key="porfiry" value="[email protected]"/>
</util:map>

您還可以透過使用 <util:map/> 元素的 'map-class' 屬性,明確控制例項化和填充的 Map 的確切型別。例如,如果我們確實需要例項化一個 java.util.TreeMap,可以使用以下配置

<util:map id="emails" map-class="java.util.TreeMap">
	<entry key="pechorin" value="[email protected]"/>
	<entry key="raskolnikov" value="[email protected]"/>
	<entry key="stavrogin" value="[email protected]"/>
	<entry key="porfiry" value="[email protected]"/>
</util:map>

如果未提供 'map-class' 屬性,容器將選擇一個 Map 實現。

使用 <util:set/>

考慮以下示例

<!-- creates a java.util.Set instance with values loaded from the supplied 'sourceSet' -->
<bean id="emails" class="org.springframework.beans.factory.config.SetFactoryBean">
	<property name="sourceSet">
		<set>
			<value>[email protected]</value>
			<value>[email protected]</value>
			<value>[email protected]</value>
			<value>[email protected]</value>
		</set>
	</property>
</bean>

上述配置使用 Spring FactoryBean 實現(即 SetFactoryBean)建立一個 java.util.Set 例項,並使用提供的 sourceSet 中的值進行初始化。

以下示例使用一個 <util:set/> 元素來建立更簡潔的表示

<!-- creates a java.util.Set instance with the supplied values -->
<util:set id="emails">
	<value>[email protected]</value>
	<value>[email protected]</value>
	<value>[email protected]</value>
	<value>[email protected]</value>
</util:set>

您還可以透過使用 <util:set/> 元素的 set-class 屬性,明確控制例項化和填充的 Set 的確切型別。例如,如果我們確實需要例項化一個 java.util.TreeSet,可以使用以下配置

<util:set id="emails" set-class="java.util.TreeSet">
	<value>[email protected]</value>
	<value>[email protected]</value>
	<value>[email protected]</value>
	<value>[email protected]</value>
</util:set>

如果未提供 set-class 屬性,容器將選擇一個 Set 實現。

aop Schema

aop 標籤用於配置 Spring 中的所有 AOP 相關內容,包括 Spring 自身的基於代理的 AOP 框架以及 Spring 與 AspectJ AOP 框架的整合。這些標籤已在題為“使用 Spring 進行面向切面程式設計”的章節中進行了全面介紹。

為了完整起見,要使用 aop Schema 中的標籤,您需要在 Spring XML 配置檔案頂部新增以下序言(程式碼段中的文字引用了正確的 Schema,以便 aop 名稱空間中的標籤對您可用)

<?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:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- bean definitions here -->

</beans>

context Schema

context 標籤用於處理與“底層實現”相關的 ApplicationContext 配置——也就是說,它們通常不是對終端使用者很重要的 Bean,而是執行 Spring 中許多“繁重”工作的 Bean,例如 BeanfactoryPostProcessors。以下程式碼段引用了正確的 Schema,以便 context 名稱空間中的元素對您可用

<?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"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- bean definitions here -->

</beans>

使用 <property-placeholder/>

此元素啟用 ${…​} 佔位符的替換,這些佔位符根據指定的屬性檔案(作為 Spring 資源位置)進行解析。此元素是一種便利機制,它為您設定了一個 PropertySourcesPlaceholderConfigurer。如果您需要更精細地控制特定的 PropertySourcesPlaceholderConfigurer 設定,可以自己明確將其定義為一個 Bean。

對於給定的應用,應該只定義一個這樣的元素,包含其所需的屬性。只要有不同的佔位符語法 (${…​}),就可以配置多個屬性佔位符。

如果您需要模組化用於替換的屬性來源,則不應建立多個屬性佔位符。相反,每個模組應該向 Environment 貢獻一個 PropertySource。或者,您可以建立自己的 PropertySourcesPlaceholderConfigurer Bean 來收集要使用的屬性。

使用 <annotation-config/>

此元素啟用 Spring 基礎設施以檢測 Bean 類中的註解

  • Spring 的 @Configuration 模型

  • @Autowired/@Inject@Value@Lookup

  • JSR-250 的 @Resource@PostConstruct@PreDestroy(如果可用)

  • JAX-WS 的 @WebServiceRef 和 EJB 3 的 @EJB(如果可用)

  • JPA 的 @PersistenceContext@PersistenceUnit(如果可用)

  • Spring 的 @EventListener

或者,您可以選擇明確啟用這些註解對應的各個 BeanPostProcessors

此元素不啟用 Spring 的 @Transactional 註解的處理;為此目的,您可以使用 <tx:annotation-driven/> 元素。類似地,Spring 的快取註解也需要明確啟用

使用 <component-scan/>

此元素在基於註解的容器配置一節中有詳細介紹。

使用 <load-time-weaver/>

此元素在Spring Framework 中使用 AspectJ 進行載入時織入一節中有詳細介紹。

使用 <spring-configured/>

此元素在使用 AspectJ 透過 Spring 進行領域物件依賴注入一節中有詳細介紹。

使用 <mbean-export/>

此元素在配置基於註解的 MBean 匯出文件中進行了詳細介紹。

Beans Schema

最後但同樣重要的是,我們有 beans Schema 中的元素。這些元素自 Spring 框架誕生之初就已存在。這裡不再展示 beans Schema 中各種元素的示例,因為它們已在依賴項和配置詳解(以及整個章節)中進行了全面介紹。

請注意,您可以向 <bean/> XML 定義新增零個或多個鍵值對。如何處理這些額外的元資料完全取決於您自己的自定義邏輯(因此通常只有在您編寫自己的自定義元素時才有用,如題為 XML Schema 編寫 的附錄中所述)。

以下示例展示了 <meta/> 元素在其周圍的 <bean/> 上下文中的用法(請注意,如果沒有任何邏輯來解釋它,元資料實際上是無用的)。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="foo" class="x.y.Foo">
		<meta key="cacheName" value="foo"/> (1)
		<property name="name" value="Rick"/>
	</bean>

</beans>
1 這是示例 meta 元素

對於前面的示例,您可以假設存在一些邏輯,該邏輯使用 bean 定義並建立利用所提供的元資料的快取基礎設施。