41. 基于 XML 模式的配置

41.1 Introduction

本附录详细介绍了 Spring 2.0 中引入的,在 Spring 2.5 和 3.0 中进行了增强和扩展的基于 XML Schema 的配置。

DTD support?

仍然完全支持使用较早的 DTD 样式创作 Spring 配置文件。

如果您放弃使用基于 XML Schema 的新方法来编写 Spring XML 配置文件,一切都不会中断。您所失去的一切就是拥有更简洁明了的配置的机会。不管 XML 配置是基于 DTD 还是基于 Schema,最终都可以归结为容器中相同的对象模型(即一个或多个BeanDefinition实例)。

转向基于 XML Schema 的配置文件的主要动机是简化 Spring XML 配置。基于*'classic'* <bean/>的方法不错,但是其通用性质会带来配置开销。

从 Spring IoC 容器的角度来看,“一切”都是一个 bean。对于 Spring IoC 容器来说,这是个好消息,因为如果所有内容都是 bean,则可以以完全相同的方式处理所有内容。但是,从开发人员的角度来看,情况并非如此。 Spring XML 配置文件中定义的对象并非都是普通的香草 bean。通常,每个 bean 需要某种程度的特定配置。

Spring 2.0 的新的基于 XML Schema 的配置解决了这个问题。 <bean/>元素仍然存在,如果需要,您可以 continue 仅使用<bean/>元素来编写“完全相同”的 Spring XML 配置样式。但是,基于 XML Schema 的新配置确实使 Spring XML 配置文件更清晰易读。另外,它允许您表达 bean 定义的意图。

要记住的关键是,新的自定义标签最适合基础结构或集成 Bean:例如 AOP,集合,事务,与第三方框架(例如 Mule)的集成等,而现有的 Bean 标签最适合于特定于应用程序的 Bean,例如 DAO,服务层对象,验证器等。

下面包含的示例将使您确信,Spring 2.0 中包含 XML Schema 支持是一个好主意。社区的接待令人鼓舞;另外,请注意,这一新的配置机制是完全可定制和可扩展的。这意味着您可以编写自己的特定于域的配置标签,以更好地表示应用程序的域。标题为第 42 章,可扩展的 XML 创作的附录涵盖了这样做的过程。

41.2 基于 XML 模式的配置

41.2.1 引用架构

要从 DTD 样式切换到新的 XML Schema 样式,您需要进行以下更改。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>

<!-- bean definitions here -->

</beans>

XML Schema 样式的等效文件为…

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

    <!-- bean definitions here -->

</beans>

Note

'xsi:schemaLocation'片段实际上不是必需的,但可以包含在内以引用模式的本地副本(在开发过程中可能有用)。

上面的 Spring XML 配置片段是样板,您可以复制并粘贴(!),然后像往常一样将<bean/>定义插入其中。但是,切换的全部目的是利用新的 Spring 2.0 XML 标签,因为它们使配置更加容易。标题为第 41.2.2 节“ util 模式”的部分演示了如何通过使用一些更常见的实用工具标签立即开始。

本章的其余部分专门显示基于新的 Spring XML Schema 的配置示例,每个新标签至少有一个示例。格式遵循前后样式,XML 的* before 片段显示旧的(但仍然是 100%合法和受支持的)样式,紧接着是 after *示例,显示基于 XML Schema 的新样式中的等效样式。

41.2.2 util 模式

首先介绍util标签。顾名思义,util标签处理常见的* utility *配置问题,例如配置集合,引用常量等。

要在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 http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!-- bean definitions here -->

</beans>

<util:constant/>

Before…

<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 的版本更加简洁,清楚地表达了开发人员的意图('inject this constant value'),并且它读起来更好。

<bean id="..." class="...">
    <property name="isolation">
        <util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
    </property>
</bean>
根据字段值设置 bean 属性或构造函数 arg

FieldRetrievingFactoryBeanFactoryBean,它检索static或非静态字段值。它通常用于检索public static final常量,然后可用于为另一个 bean 设置属性值或构造函数 arg。

在下面找到一个示例,该示例通过使用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 的非静态(实例)字段,如FieldRetrievingFactoryBean类的 API 文档中所述。

在 Spring 中,将枚举值作为属性或构造函数参数注入到 bean 中非常容易,因为您实际上不必“做任何事情”或不了解 Spring 内部(甚至是诸如FieldRetrievingFactoryBean之类的类)。让我们看一个例子,看看注入枚举值有多容易。考虑一下这个 JDK 5 枚举:

package javax.persistence;

public enum PersistenceContextType {

    TRANSACTION,
    EXTENDED

}

现在考虑类型为PersistenceContextType的二传手:

package example;

public class Client {

    private PersistenceContextType persistenceContextType;

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

}
  • 以及相应的 bean 定义:
<bean class="example.Client">
    <property name="persistenceContextType" value="TRANSACTION" />
</bean>

这也适用于经典的类型安全的仿真枚举(在 JDK 1.4 和 JDK 1.3 上); Spring 将自动尝试将字符串属性值与枚举类上的常量进行匹配。

<util:property-path/>

Before…

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

<!-- will result 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属性。

After…

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

<!-- will result 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的形式。

使用\ <>设置 bean 属性或构造函数参数

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>

// will result 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 评估路径:

<!-- will result 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 名称是属性路径。

<!-- will result 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>

结果类型可以在实际定义中专门设置。对于大多数用例来说,这不是必需的,但对于某些情况却可以使用。请参阅 Javadocs 以获取有关此功能的更多信息。

<util:properties/>

Before…

<!-- 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实例。

After…

<!-- 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/>

Before…

<!-- 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>[emailprotected]</value>
            <value>[emailprotected]</value>
            <value>[emailprotected]</value>
            <value>[emailprotected]</value>
        </list>
    </property>
</bean>

上面的配置使用 Spring FactoryBean实现ListFactoryBean来创建java.util.List实例,该实例使用从提供的sourceList中获取的值进行初始化。

After…

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

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

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

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

<util:map/>

Before…

<!-- 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="[emailprotected]"/>
            <entry key="raskolnikov" value="[emailprotected]"/>
            <entry key="stavrogin" value="[emailprotected]"/>
            <entry key="porfiry" value="[emailprotected]"/>
        </map>
    </property>
</bean>

上面的配置使用 Spring FactoryBean实现MapFactoryBean来创建java.util.Map实例,该实例使用从提供的'sourceMap'中获取的键值对进行初始化。

After…

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

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

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

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

<util:set/>

Before…

<!-- 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>[emailprotected]</value>
            <value>[emailprotected]</value>
            <value>[emailprotected]</value>
            <value>[emailprotected]</value>
        </set>
    </property>
</bean>

上面的配置使用 Spring FactoryBean实现SetFactoryBean来创建java.util.Set实例,该实例使用从提供的'sourceSet'中获取的值进行初始化。

After…

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

您还可以通过使用<util:set/>元素上的'set-class'属性来显式控制将实例化并填充的Set的确切类型。例如,如果我们确实需要实例化java.util.TreeSet,则可以使用以下配置:

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

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

41.2.3 jee 模式

jee标签处理与 Java EE(Java 企业版)相关的配置问题,例如查找 JNDI 对象和定义 EJB 引用。

要在jee模式中使用标记,您需要在 Spring XML 配置文件的顶部具有以下序言;以下代码段中的文本引用了正确的架构,以便您可以使用jee名称空间中的标记。

<?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:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"> <!-- bean definitions here -->

</beans>

<jee:jndi-lookup/> (simple)

Before…

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/MyDataSource"/>
</bean>
<bean id="userDao" class="com.foo.JdbcUserDao">
    <!-- Spring will do the cast automatically (as usual) -->
    <property name="dataSource" ref="dataSource"/>
</bean>

After…

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource"/>

<bean id="userDao" class="com.foo.JdbcUserDao">
    <!-- Spring will do the cast automatically (as usual) -->
    <property name="dataSource" ref="dataSource"/>
</bean>

<jee:jndi-lookup/>(具有单个 JNDI 环境设置)

Before…

<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/MyDataSource"/>
    <property name="jndiEnvironment">
        <props>
            <prop key="foo">bar</prop>
        </props>
    </property>
</bean>

After…

<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource">
    <jee:environment>foo=bar</jee:environment>
</jee:jndi-lookup>

<jee:jndi-lookup/>(具有多个 JNDI 环境设置)

Before…

<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/MyDataSource"/>
    <property name="jndiEnvironment">
        <props>
            <prop key="foo">bar</prop>
            <prop key="ping">pong</prop>
        </props>
    </property>
</bean>

After…

<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource">
    <!-- newline-separated, key-value pairs for the environment (standard Properties format) -->
    <jee:environment>
        foo=bar
        ping=pong
    </jee:environment>
</jee:jndi-lookup>

<jee:jndi-lookup/> (complex)

Before…

<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/MyDataSource"/>
    <property name="cache" value="true"/>
    <property name="resourceRef" value="true"/>
    <property name="lookupOnStartup" value="false"/>
    <property name="expectedType" value="com.myapp.DefaultFoo"/>
    <property name="proxyInterface" value="com.myapp.Foo"/>
</bean>

After…

<jee:jndi-lookup id="simple"
        jndi-name="jdbc/MyDataSource"
        cache="true"
        resource-ref="true"
        lookup-on-startup="false"
        expected-type="com.myapp.DefaultFoo"
        proxy-interface="com.myapp.Foo"/>

<jee:local-slsb/> (simple)

<jee:local-slsb/>标记配置对 EJB Stateless SessionBean 的引用。

Before…

<bean id="simple"
        class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
    <property name="jndiName" value="ejb/RentalServiceBean"/>
    <property name="businessInterface" value="com.foo.service.RentalService"/>
</bean>

After…

<jee:local-slsb id="simpleSlsb" jndi-name="ejb/RentalServiceBean"
        business-interface="com.foo.service.RentalService"/>

<jee:local-slsb/> (complex)

<bean id="complexLocalEjb"
        class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
    <property name="jndiName" value="ejb/RentalServiceBean"/>
    <property name="businessInterface" value="com.foo.service.RentalService"/>
    <property name="cacheHome" value="true"/>
    <property name="lookupHomeOnStartup" value="true"/>
    <property name="resourceRef" value="true"/>
</bean>

After…

<jee:local-slsb id="complexLocalEjb"
        jndi-name="ejb/RentalServiceBean"
        business-interface="com.foo.service.RentalService"
        cache-home="true"
        lookup-home-on-startup="true"
        resource-ref="true">

<jee:remote-slsb/>

<jee:remote-slsb/>标记配置对remote EJB Stateless SessionBean 的引用。

Before…

<bean id="complexRemoteEjb"
        class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
    <property name="jndiName" value="ejb/MyRemoteBean"/>
    <property name="businessInterface" value="com.foo.service.RentalService"/>
    <property name="cacheHome" value="true"/>
    <property name="lookupHomeOnStartup" value="true"/>
    <property name="resourceRef" value="true"/>
    <property name="homeInterface" value="com.foo.service.RentalService"/>
    <property name="refreshHomeOnConnectFailure" value="true"/>
</bean>

After…

<jee:remote-slsb id="complexRemoteEjb"
        jndi-name="ejb/MyRemoteBean"
        business-interface="com.foo.service.RentalService"
        cache-home="true"
        lookup-home-on-startup="true"
        resource-ref="true"
        home-interface="com.foo.service.RentalService"
        refresh-home-on-connect-failure="true">

41.2.4 lang 模式

lang标签用于处理以动态语言(例如 JRuby 或 Groovy)编写的对象作为 Spring 容器中的 bean。

标题为第 35 章,动态语言支持的一章全面介绍了这些标签(以及动态语言支持)。请确实参考该章以获取有关此支持和lang标签本身的完整详细信息。

为了完整起见,要在lang模式中使用标记,您需要在 Spring XML 配置文件的顶部具有以下序言;以下代码段中的文本引用了正确的架构,以便您可以使用lang名称空间中的标记。

<?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:lang="http://www.springframework.org/schema/lang" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd"> <!-- bean definitions here -->

</beans>

41.2.5 jms 模式

jms标签用于配置与 JMS 相关的 bean,例如 Spring 的MessageListenerContainers。这些标签在JMS chapter标题为第 30.7 节“ JMS 名称空间支持”的部分中进行了详细说明。请确实参考该章以获取有关此支持和jms标签本身的完整详细信息。

为了完整起见,要在jms模式中使用标记,您需要在 Spring XML 配置文件的顶部具有以下序言;以下代码段中的文本引用了正确的架构,以便您可以使用jms名称空间中的标记。

<?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:jms="http://www.springframework.org/schema/jms" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd"> <!-- bean definitions here -->

</beans>

41.2.6 tx(Transaction)模式

tx标签用于在 Spring 的全面事务支持中配置所有这些 bean。这些标签在标题为第十七章,TransactionManagement的章节中介绍。

Tip

强烈建议您查看 Spring 发行版随附的'spring-tx.xsd'文件。这个文件(当然)是 Spring 事务配置的 XML 模式,它涵盖了tx名称空间中的所有各种标签,包括属性默认值等。该文件已内联记录,因此出于遵守 DRY(请勿重复自己)的原则,此处不再赘述。

为了完整起见,要在tx模式中使用标记,您需要在 Spring XML 配置文件的顶部具有以下序言;以下代码段中的文本引用了正确的架构,以便您可以使用tx名称空间中的标记。

<?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"
        xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->

</beans>

Note

通常,在tx名称空间中使用标记时,您还将使用aop名称空间中的标记(因为使用 AOP 实现了 Spring 中的声明式事务支持)。上面的 XML 代码段包含引用aop模式所需的相关行,以便您可以使用aop名称空间中的标记。

41.2.7 aop 模式

aop标签处理在 Spring 中配置 AOP 的所有事情:这包括 Spring 自己的基于代理的 AOP 框架以及 Spring 与 AspectJ AOP 框架的集成。这些标签在标题为第 11 章,使用 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 http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->

</beans>

41.2.8 上下文架构

context标签处理与管道相关的ApplicationContext配置-即通常不是对最终用户重要的 bean,而是在 Spring 中需要大量工作的 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 http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->

</beans>

Note

context模式仅在 Spring 2.5 中引入。

<property-placeholder/>

此元素激活${…}占位符的替换,该占位符针对指定的属性文件(作为Spring 资源位置)解析。此元素是为您设置PropertyPlaceholderConfigurer的便捷机制;如果您需要对PropertyPlaceholderConfigurer的更多控制,请自己明确定义。

<annotation-config/>

激活 Spring 基础结构以在 bean 类中检测各种 Comments:Spring 的@Required@Autowired,以及 JSR 250 的@PostConstruct@PreDestroy@Resource(如果可用),以及 JPA 的@PersistenceContext@PersistenceUnit(如果可用)。或者,您可以选择为这些 Comments 显式激活单独的BeanPostProcessors

Note

这个元素不会激活 Spring 的@Transactional注解。为此,请使用<tx:annotation-driven/>元素。

<component-scan/>

第 7.9 节“基于 Comments 的容器配置”中对此元素进行了详细说明。

<load-time-weaver/>

第 11.8.4 节“在 Spring 框架中使用 AspectJ 进行加载时编织”中对此元素进行了详细说明。

<spring-configured/>

第 11.8.1 节“使用 AspectJ 依赖 Spring 注入域对象”中对此元素进行了详细说明。

<mbean-export/>

第 31.4.3 节“配置基于 Comments 的 MBean 导出”中对此元素进行了详细说明。

41.2.9 工具架构

tool标记用于要将特定于工具的元数据添加到自定义配置元素中的情况。然后,知道该元数据的工具就可以使用此元数据,然后这些工具可以使用它们执行几乎所有其想做的事情(验证等)。

此版本的 Spring 中未记录tool标签,因为它们正在接受审核。如果您是第三方工具供应商,并且希望为该审核过程做出贡献,请通过 Spring 邮件列表发送邮件。当前支持的tool标签可以在 Spring 源代码发行版'src/org/springframework/beans/factory/xml'目录的'spring-tool.xsd'文件中找到。

41.2.10 jdbc 模式

jdbc标记使您可以快速配置嵌入式数据库或初始化现有数据源。这些标签分别记录在第 19.8 节“嵌入式数据库支持”???中。

要在jdbc模式中使用标记,您需要在 Spring XML 配置文件的顶部具有以下序言;以下代码段中的文本引用了正确的架构,以便您可以使用jdbc名称空间中的标记。

<?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:jdbc="http://www.springframework.org/schema/jdbc" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd"> <!-- bean definitions here -->

</beans>

41.2.11 缓存架构

cache标签可用于启用对 Spring 的@CacheEvict@CachePut@CachingComments 的支持。它还支持基于声明式 XML 的缓存。有关详情,请参见第 36.3.6 节“启用缓存 Comments”第 36.5 节“基于声明式 XML 的缓存”

要在cache模式中使用标记,您需要在 Spring XML 配置文件的顶部具有以下序言;以下代码段中的文本引用了正确的架构,以便您可以使用cache名称空间中的标记。

<?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:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- bean definitions here -->

</beans>

41.2.12 Bean 模式

最后但并非最不重要的一点是,我们在beans模式中具有标签。自框架诞生以来,这些标签与 Spring 相同。此处未显示beans模式中各种标签的示例,因为它们在第 7.4.2 节“详细的依赖关系和配置”中(以及实际上在整个chapter中)已全面介绍。

在 Spring 2.0 中,bean 标记本身是新事物,它是任意 bean 元数据的想法。在 Spring 2.0 中,现在可以向<bean/> XML 定义添加零个或多个键/值对。使用此额外的元数据进行的操作(如果有的话)完全取决于您自己的自定义逻辑(因此,通常只有在您按照标题为第 42 章,可扩展的 XML 创作的附录中所述编写自己的自定义标签时才能使用)。

在周围的<bean/>上下文中找到<meta/>标签的示例(请注意,没有任何逻辑来解释它,元数据实际上是毫无用处的)。

<?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 http://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 定义并使用提供的元数据构建一些缓存基础结构。