跳到主要内容

XML 架构

ChatGPT-4o-mini 中英对照 XML Schemas

XML 架构

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

util 模式

如其名所示,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>
xml

使用 <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>
xml

前面的配置使用了一个 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>
xml

从字段值设置 Bean 属性或构造函数参数

FieldRetrievingFactoryBean 是一个 FactoryBean,用于检索 static 或非 static 字段值。它通常用于检索 public static final 常量,这些常量可以用于设置另一个 bean 的属性值或构造函数参数。

以下示例展示了如何通过使用 staticField 属性来暴露一个 static 字段:

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

还有一种便捷的使用形式,其中 static 字段被指定为 bean 名称,如下例所示:

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

这确实意味着对 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>
xml

您还可以访问另一个 bean 的非静态(实例)字段,具体说明请参见 FieldRetrievingFactoryBean 类的 API 文档。

在 Spring 中,将枚举值注入到 bean 中作为属性或构造函数参数是非常简单的。您实际上不需要做任何事情,也不需要了解 Spring 的内部实现(甚至不需要了解像 FieldRetrievingFactoryBean 这样的类)。以下示例枚举展示了注入枚举值是多么简单:

package jakarta.persistence;

public enum PersistenceContextType {

TRANSACTION,
EXTENDED
}
java

现在考虑以下类型为 PersistenceContextType 的 setter 及其对应的 bean 定义:

package example;

public class Client {

private PersistenceContextType persistenceContextType;

public void setPersistenceContextType(PersistenceContextType type) {
this.persistenceContextType = type;
}
}
java
<bean class="example.Client">
<property name="persistenceContextType" value="TRANSACTION"/>
</bean>
xml

使用 <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"/>
xml

前面的配置使用了一个 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"/>
xml

<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>
xml

在以下示例中,路径会针对内部 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>
xml

还有一种简化形式,其中 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"/>
xml

此表单确实意味着在 bean 的名称上没有选择。对它的任何引用也必须使用相同的 id,即路径。如果作为内部 bean 使用,则根本不需要引用它,正如以下示例所示:

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

您可以在实际定义中专门设置结果类型。这对于大多数用例来说不是必需的,但有时可能会很有用。有关此功能的更多信息,请参见 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>
xml

前面的配置使用了一个 Spring FactoryBean 实现(PropertiesFactoryBean)来实例化一个 java.util.Properties 实例,该实例的值是从提供的 Resource 位置加载的。

以下示例使用 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"/>
xml

使用 <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>
xml

前面的配置使用了一个 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>
xml

您还可以通过在 <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>
xml

如果没有提供 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="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>
xml

前面的配置使用了一个 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>
xml

您还可以通过在 <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>
xml

如果没有提供 '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>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
<value>stavrogin@gov.org</value>
<value>porfiry@gov.org</value>
</set>
</property>
</bean>
xml

前面的配置使用了一个 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>
xml

您还可以通过在 <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>
xml

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

aop 模式

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>
xml

context 模式

context 标签处理与 ApplicationContext 配置相关的基础设施 — 即通常不是对最终用户重要的 bean,而是执行大量“繁重”工作的 bean,例如 BeanfactoryPostProcessors。以下代码片段引用了正确的模式,以便 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>
xml

使用 <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 导出配置部分中详细介绍。

The Beans Schema

最后但同样重要的是,我们有 beans 模式中的元素。这些元素自框架诞生之初就已经存在于 Spring 中。beans 模式中各种元素的示例在这里没有展示,因为它们在 依赖关系和配置详细信息 中得到了相当全面的覆盖(实际上,在整个 章节 中也是如此)。

请注意,您可以向 <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>
xml
  • 这是示例 meta 元素

在前面的例子中,你可以假设有一些逻辑会使用 bean 定义,并设置一些缓存基础设施,这些基础设施使用提供的元数据。