# 9.1XML Schemas

附录的本部分列出了和核心容器相关的XML schemas。

## 9.1.1 util Schema

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

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

```markup
<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上隔离属性的值设置为java.sql.Connection.TRANSACTION\_SERIALIZABLE常量的值。 这一切都很好，但它很冗长，并且（不必要地）将Spring的内部管道暴露给最终用户。

以下基于XML Schema的版本更简洁，清楚地表达了开发人员的意图（“注入此常量值”），并且它可读性更好：

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

**使用字段值设置Bean属性或者构造函数参数**

FieldRetrievingFactoryBean是一个FactoryBean，用于检索静态或非静态字段值。 它通常用于检索公共静态最终常量，然后可以使用它来为另一个bean设置属性值或构造函数参数。

以下示例显示了如何使用staticField属性公开静态字段：

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

还有一个便捷使用形式，其中静态字段被指定为bean名称，如以下示例所示：

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

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

```markup
<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
package javax.persistence;

public enum PersistenceContextType {

    TRANSACTION,
    EXTENDED
}
```

考虑如下PersistenceContextType的set方法和相应的bean定义：

```java
package example;

public class Client {

    private PersistenceContextType persistenceContextType;

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

```markup
<bean class="example.Client">
    <property name="persistenceContextType" value="TRANSACTION"/>
</bean>
```

**使用Using \<util:property-path/>**

考虑如下例子：

```markup
<!-- 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 />元素：

```markup
<!-- 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使用的路径：

```markup
// 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>
```

下面的例子中，path被用作内部bean：

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

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

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

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

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

考虑下面的例子：

```markup
<!-- 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>
```

上面的配置使用了FactoryBean实现（PropertiesFactoryBean）实例化了java.util.Properties，并从一个特定的Resource地址加载值。

以下示例使用util：properties元素来进行更简洁的表示：

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

考虑下面的例子：

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

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

```markup
<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/>**

考虑下面的例子：

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

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

```markup
<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/>**

考虑下面的例子：

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

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

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

## 9.1.2 aop Schema

aop标签用于配置Spring中的所有AOP，包括Spring自己的基于代理的AOP框架和Spring与AspectJ AOP框架的集成。 这些标签在题为“面向方面编程与Spring”的章节中进行了全面介绍。

为了完整性，要在aop模式中使用标记，你需要在Spring XML配置文件的顶部包含以下前导码（片段中的文本引用正确的模式，以便aop命名空间中的标记可以被你使用）：

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

## 9.1.3 context Schema

context标记处理与管道相关的ApplicationContext配置 - 也就是说，通常不是对最终用户很重要的bean，而是在Spring中执行大量“grunt”工作的bean，例如BeanfactoryPostProcessors。 以下代码段引用了正确的架构，以便你可以使用上下文命名空间中的元素：

```markup
<?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资源位置）解析的。 此元素是一种便捷机制，可为你设置PropertyPlaceholderConfigurer。 如果你需要更多地控制PropertyPlaceholderConfigurer，你可以自己明确定义一个。

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

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

* Spring的@Configuration模型
* @Autowired / @Inject和@Value
* JSR-250的@Resource，@PostConstruct和@PreDestroy（如果有的话）
* JPA的@PersistenceContext和@PersistenceUnit（如果可用）
* Spring的@EventListener

或者，你可以选择显式激活这些注解的各个BeanPostProcessors。

> 此元素不会激活Spring的@Transactional注解的处理; 你可以使用\<tx：annotation-driven />元素来实现此目的。 同样，Spring的缓存注解也需要明确启用。

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

详细信息请参考：annotation-based container configuration.

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

详细信息请参考：load-time weaving with AspectJ in the Spring Framework.

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

详细信息请参考：using AspectJ to dependency inject domain objects with Spring.

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

详细信息请参考： configuring annotation-based MBean export.

## 9.1.4 Beans Schema

最后但并非最不重要的是，我们在beans schema中有元素。自框架诞生以来，这些元素一直存在于Spring中。 这里没有显示bean schema中各种元素的示例，因为它们在依赖性和配置中得到了相当全面的介绍（实际上，在整个章节中）。

请注意，你可以向\<bean/> XML定义添加零个或多个键值对。 如果有的话，使用这些额外的元数据完成的工作完全取决于你自己的自定义逻辑（因此，如果你按照标题为XML Schema Authoring的附录中所述编写自己的自定义元素，通常只会使用它。)

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

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

在前面的示例中，你可以假设有一些逻辑使用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://docs.flydean.com/spring-framework-documentation5/core-technologies/appendix/9.1xml-schemas.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.
