# 10.1. XML 模式

附录的这一部分列出了与核心容器相关的 XML 模式。

**10.1.1. `util`库**

顾名思义，`util`标签处理常见的实用程序配置问题，例如配置集合、引用常量等。要使用`util`中的标签，您需要在 Spring XML 配置文件的顶部有以下前导码（片段中的文本引用正确的模式，以便您可以使用`util`命名空间中的标签）：

```xml
<?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 定义：

```xml
<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 的版本更简洁，清楚地表达了开发者的意图（“注入这个常量值”），并且读起来更好：

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

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

[`FieldRetrievingFactoryBean`](https://docs.spring.io/spring-framework/docs/5.3.22/javadoc-api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html) 是一个`FactoryBean`用来检索一个`static`或非静态字段值的。它通常用于检索`public` `static` `final`常量，然后可用于为另一个 bean 设置属性值或构造函数参数。

以下示例显示了如何使用 [`staticField`](https://docs.spring.io/spring-framework/docs/5.3.22/javadoc-api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField\(java.lang.String\)) 属性公开`static`字段：

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

还有一种方便的使用形式，其中该`static`字段被指定为 bean 名称，如以下示例所示：

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

这确实意味着 bean`id`是什么不再有任何选择（因此引用它的任何其他 bean 也必须使用这个更长的名称），但是这种形式定义非常简洁，用作内部 bean 非常方便因为`id`不必为 bean 引用指定 ，如以下示例所示：

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

您还可以访问另一个 bean 的非静态（实例）字段，如 [`FieldRetrievingFactoryBean`](https://docs.spring.io/spring-framework/docs/5.3.22/javadoc-api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html) 类的 API 文档中所述。

在 Spring 中很容易将枚举值作为属性或构造函数参数注入到 bean 中。您实际上不必对 Spring 内部结构（甚至诸如`FieldRetrievingFactoryBean`. 以下示例枚举显示了注入枚举值是多么容易：

```java
package javax.persistence;

public enum PersistenceContextType {

    TRANSACTION,
    EXTENDED
}
```

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

```java
package example;

public class Client {

    private PersistenceContextType persistenceContextType;

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

**使用`<util:property-path/>`**

考虑以下示例：

```xml
<!-- 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` ） ，该 bean的值等于`testBean` bean 的`age`属性。

现在考虑以下示例，它添加了一个`<util:property-path/>`元素：

```xml
<!-- 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"/>
```

`path`元素的属性值`<property-path/>`遵循`beanName.beanProperty` 的形式 。在这种情况下，它获取名为 `testBean` 的 bean 的`age`属性。该`age`属性的值为`10`。

**`<util:property-path/>`用于设置 Bean 属性或构造函数参数**

`PropertyPathFactoryBean`是`FactoryBean`用于评估给定目标对象上的属性路径的。目标对象可以直接指定，也可以通过 bean 名称指定。然后，您可以在另一个 bean 定义中将此值用作属性值或构造函数参数。

下面的示例显示了一个用于另一个 bean 的路径，按名称：

```xml
<!-- 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 评估路径：

```xml
<!-- 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 名称是属性路径。以下示例显示了快捷方式：

```xml
<!-- 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，则根本不需要引用它，如以下示例所示：

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

您可以在实际定义中具体设置结果类型。对于大多数用例来说，这不是必需的，但有时它可能很有用。有关此功能的更多信息，请参阅 javadoc。

**使用`<util:properties/>`**

考虑以下示例：

```xml
<!-- 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`包含从提供的[`Resource`](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources)位置加载的值。

下面的示例使用一个`util:properties`元素进行更简洁的表示：

```xml
<!-- 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/>`**

考虑以下示例：

```xml
<!-- 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/>`元素进行更简洁的表示：

```xml
<!-- 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`，我们可以使用以下配置：

```xml
<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`实现。

**使用`<util:map/>`**

考虑以下示例：

```xml
<!-- 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/>`元素进行更简洁的表示：

```xml
<!-- 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`，我们可以使用以下配置：

```xml
<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`实现。

**使用`<util:set/>`**

考虑以下示例：

```xml
<!-- 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/>`元素进行更简洁的表示：

```xml
<!-- 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`，我们可以使用以下配置：

```xml
<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`实现。

**10.1.2. `aop` Schema**

`aop`标签处理在 Spring 中配置所有 AOP，包括 Spring 自己的基于代理的 AOP 框架和 Spring 与 AspectJ AOP 框架的集成。[这些标签在标题为Aspect Oriented Programming with Spring](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop)的章节中全面介绍。

为了完整起见，要使用`aop`库中的标签，您需要在 Spring XML 配置文件的顶部有以下序言（片段中的文本引用正确的模式，以便`aop`命名空间中的标签可用于你）：

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

**10.1.3. `context` Schema**

`context`标签处理与管道相关的`ApplicationContext`配置——也就是说，通常不是对最终用户很重要的 bean，而是在 Spring 中完成大量“咕噜”工作的 bean，例如`BeanfactoryPostProcessors`. 以下代码段引用了正确的架构，以便您可以使用`context`命名空间中的元素：

```xml
<?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 资源位置](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources)）进行解析。此元素是一种便利机制，可为您设置一个[`PropertySourcesPlaceholderConfigurer`](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-placeholderconfigurer)。如果您需要对特定`PropertySourcesPlaceholderConfigurer`设置进行更多控制 ，您可以自己将其显式定义为 bean。

**使用`<annotation-config/>`**

此元素激活 Spring 基础结构以检测 bean 类中的注解：

* spring [`@Configuration`](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-metadata)模型
* [`@Autowired`/`@Inject`](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-annotation-config) , `@Value`, 和`@Lookup`
* JSR-250 的`@Resource`、`@PostConstruct`和`@PreDestroy`（如果可用）
* JAX-WS`@WebServiceRef`和 EJB 3 `@EJB`（如果可用）
* JPA`@PersistenceContext`和`@PersistenceUnit`（如果有）
* spring的[`@EventListener`](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#context-functionality-events-annotation)

或者，您可以选择为这些注解显式激活自定义的`BeanPostProcessors`。

该元素不会激活 Spring 的 [`@Transactional`](https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#transaction-declarative-annotations)注解处理；您可以为此目的使用[`<tx:annotation-driven>`](https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#tx-decl-explained) 元素。同样，Spring 的 [缓存注解](https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache-annotations)也需要显式 [启用](https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache-annotation-enable)。

**使用`<component-scan/>`**

这个元素在基于[注解的容器配置](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-annotation-config)一节中有详细说明。

**使用`<load-time-weaver/>`**

此元素[在 Spring Framework 中使用 AspectJ 进行加载时编织](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-aj-ltw)的部分中有详细说明。

**使用`<spring-configured/>`**

这个元素在[使用 AspectJ 通过 Spring 依赖注入域对象](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-atconfigurable)的部分中有详细说明。

**使用`<mbean-export/>`**

此元素在有关[配置基于注解的 MBean 导出](https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#jmx-context-mbeanexport)的部分中有详细说明。

**10.1.4. Bean Schema**

最后但同样重要的是，我们在`beans` Schema中有元素。这些元素自框架诞生之初就存在于 Spring 中。这里没有显示`beans`模式中各种元素的示例，因为它们在[依赖项和详细配置中](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-properties-detailed)被非常全面地介绍 （实际上，在整个[章节](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans)中）。

请注意，您可以向`<bean/>`XML 定义添加零个或多个键值对。如果有的话，如何使用这些额外的元数据完全取决于您自己的自定义逻辑（因此通常仅在您编写自己的自定义元素时使用，如题为[XML Schema Authoring](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#xml-custom)的附录中所述）。

以下示例显示了`<bean/>` 上下文中的`<meta/>`元素（请注意，如果没有任何逻辑来解释它，元数据实际上是无用的）。

```xml
<?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"/> 
        <property name="name" value="Rick"/>
    </bean>

</beans>
```

这是示例`meta`元素

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.shiker.tech/spring-he-xin-gong-neng/10.-fu-lu/10.1.-xml-mo-shi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
