XML Schemas

此附录部分列出了与核心容器相关的 XML 架构。

The util Schema

顾名思义,util 标记处理常见的实用程序配置问题,例如配置集合、引用常量等等。要使用 util 架构中的标记,您需要在 Spring XML 配置文件顶部有以下前缀(代码段中的文本引用了正确的架构,以便您使用 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>

Using <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 架构的版本更为简洁,清楚地表达了开发人员的意图(“注入此常量值”),并且更具可读性:

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

Setting a Bean Property or Constructor Argument from a Field Value

FieldRetrievingFactoryBean是一个[FactoryBean]用来检索[static]或非静态字段值。它通常用于检索[public][static][final]常量,然后可用于设置另一个 Bean 的属性值或构造函数参数。

以下示例演示了如何通过使用 @ [1] 的属性 @https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String) [staticField] 暴露 static 字段:

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

还有一种便利的使用形式,其中 static 字段指定为 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 的非静态(实例)字段,如 @https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html [FieldRetrievingFactoryBean] 类的 API 文档中所述。

将枚举值注入 bean 中作为属性或构造函数参数很容易在 Spring 中完成。实际上,您不必执行任何操作或了解任何有关 Spring 内部(甚至有关诸如 FieldRetrievingFactoryBean 之类的类)的信息。以下示例枚举显示了注入枚举值有多么容易:

  • Java

  • Kotlin

public enum PersistenceContextType {

	TRANSACTION,
	EXTENDED
}
enum class PersistenceContextType {

	TRANSACTION,
	EXTENDED
}

现在考虑以下 PersistenceContextType 类型和相应 bean 定义的 setter:

  • Java

  • Kotlin

public class Client {

	private PersistenceContextType persistenceContextType;

	public void setPersistenceContextType(PersistenceContextType type) {
		this.persistenceContextType = type;
	}
}
class Client {

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

Using <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)来创建 Bean(类型为 int),称为 testBean.age,其值等于 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

Using <util:property-path/> to Set a Bean Property or Constructor Argument

PropertyPathFactoryBeanFactoryBean,它在一个给定的目标对象上评估一个属性路径。目标对象可以通过 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 以获取有关此特性的更多信息。

Using <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)通过从提供的 Resource位置加载的值来初始化 `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"/>

Using <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>pechorin@hero.org</value>
			<value>raskolnikov@slums.org</value>
			<value>stavrogin@gov.org</value>
			<value>porfiry@gov.org</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>pechorin@hero.org</value>
	<value>raskolnikov@slums.org</value>
	<value>stavrogin@gov.org</value>
	<value>porfiry@gov.org</value>
</util:list>

还可以使用 <util:list/> 元素上的 list-class 属性显式控制所实例化和填充的 List 的确切类型。例如,如果我们真的需要实例化 java.util.LinkedList,我们可以使用以下配置:

<util:list id="emails" list-class="java.util.LinkedList">
	<value>jackshaftoe@vagabond.org</value>
	<value>eliza@thinkingmanscrumpet.org</value>
	<value>vanhoek@pirate.org</value>
	<value>d'Arcachon@nemesis.org</value>
</util:list>

如果没有提供 list-class 属性,容器将选择 List 实现。

Using <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="pechorin@hero.org"/>
			<entry key="raskolnikov" value="raskolnikov@slums.org"/>
			<entry key="stavrogin" value="stavrogin@gov.org"/>
			<entry key="porfiry" value="porfiry@gov.org"/>
		</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="pechorin@hero.org"/>
	<entry key="raskolnikov" value="raskolnikov@slums.org"/>
	<entry key="stavrogin" value="stavrogin@gov.org"/>
	<entry key="porfiry" value="porfiry@gov.org"/>
</util:map>

还可以使用 <util:map/> 元素上的 ’map-class'` 属性显式控制所实例化和填充的 Map 的确切类型。例如,如果我们真的需要实例化 java.util.TreeMap,我们可以使用以下配置:

<util:map id="emails" map-class="java.util.TreeMap">
	<entry key="pechorin" value="pechorin@hero.org"/>
	<entry key="raskolnikov" value="raskolnikov@slums.org"/>
	<entry key="stavrogin" value="stavrogin@gov.org"/>
	<entry key="porfiry" value="porfiry@gov.org"/>
</util:map>

如果没有提供 ’map-class'` 属性,容器将选择 Map 实现。

Using <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>pechorin@hero.org</value>
			<value>raskolnikov@slums.org</value>
			<value>stavrogin@gov.org</value>
			<value>porfiry@gov.org</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>pechorin@hero.org</value>
	<value>raskolnikov@slums.org</value>
	<value>stavrogin@gov.org</value>
	<value>porfiry@gov.org</value>
</util:set>

您还可以使用 <util:set/> 元素上的 set-class 属性明确地控制要实例化和填充的 Set 的确切类型。例如,如果我们确实需要实例化 java.util.TreeSet,我们可以使用以下配置:

<util:set id="emails" set-class="java.util.TreeSet">
	<value>pechorin@hero.org</value>
	<value>raskolnikov@slums.org</value>
	<value>stavrogin@gov.org</value>
	<value>porfiry@gov.org</value>
</util:set>

如果没有提供 set-class 属性,则容器将选择 Set 实现。

The aop Schema

aop 标记与在 Spring 中配置所有 AOP 相关的事物有关,包括 Spring 自有的基于代理的 AOP 框架和 Spring 与 AspectJ AOP 框架的集成。这些标记在 Aspect Oriented Programming with Spring 一章中有全面的介绍。

为了完整起见,要在 aop 架构中使用这些标记,您需要在 Spring XML 配置文件的顶部添加以下前导(片段中的文本引用正确的架构,以便您可以使用 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>

The context Schema

context 标记处理与管道相关的 ApplicationContext 配置,即通常不是对最终用户重要的 Bean,而是像 BeanfactoryPostProcessors 一样在 Spring 中执行大量“基础”工作的 Bean。以下片段引用正确的架构,以便您可以使用 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>

Using <property-placeholder/>

该元素会替换 ${…​}`占位符,这是针对特定的属性文件(作为一个 Spring resource location)来解析的。该元素是一种便利机制,它可为您设置一个 `PropertySourcesPlaceholderConfigurer。如果您需要对特定的 `PropertySourcesPlaceholderConfigurer`设置有更多的控制权,则可以自己将其明确定义为 bean。

对于给定的应用程序,只应使用它所需的属性定义一个这样的元素。只要占位符语法不同(${…​}),则可以配置多个属性占位符。 如果您需要模块化用于替换的属性源,则不应创建多个属性占位符。相反,每个模块都应向 Environment 贡献一个 PropertySource。或者,您可以创建自己的 PropertySourcesPlaceholderConfigurer Bean 来收集要使用的属性。

Using <annotation-config/>

此元素激活 Spring 基础设施以检测 Bean 类中的注释:

  • Spring’s @Configuration model

  • @Autowired/@Inject, @Value, and @Lookup

  • JSR-250 的 @Resource@PostConstruct@PreDestroy (如果有的话)

  • JAX-WS 的 @WebServiceRef 和 EJB 3 的 @EJB (如果有的话)

  • JPA 的 @PersistenceContext@PersistenceUnit (如果有的话)

  • Spring’s @EventListener

或者,您可以选择明确激活那些注释的各个 BeanPostProcessors

此元素不会激活对 Spring 的 @Transactional 注解的处理; 您可以使用 <tx:annotation-driven/> 元素用于该目的。同样,Spring 的 caching annotations 也需要被明确地 enabled

Using <component-scan/>

该元素在 annotation-based container configuration 一节中有详细介绍。

Using <load-time-weaver/>

该元素在关于 load-time weaving with AspectJ in the Spring Framework的部分中有详细说明。

Using <spring-configured/>

该元素在关于 using AspectJ to dependency inject domain objects with Spring的部分中有详细说明。

Using <mbean-export/>

该元素在关于 configuring annotation-based MBean export的部分中有详细说明。

The Beans Schema

最后但并非最不重要的是,我们有 `beans`模式中的元素。自框架的出现之初,这些元素就在 Spring 中出现。这里没有显示 `beans`模式中各种元素的示例,这是因为 dependencies and configuration in detail(实际上还有整个 chapter)对这些元素的介绍很全面。

请注意,可以向 <bean/> XML 定义中添加零个或多个键值对。对该额外元数据进行什么(如果有的话),完全由你自己的自定义逻辑决定(因此通常仅当按 XML Schema Authoring 一节中所述编写自己的自定义元素时才有用)。

以下示例显示了 <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 定义,并设置使用提供元数据的某些缓存基础设施。