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>
使用 <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>
从字段值设置 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>
还有一种方便的用法形式,其中 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 文档中所述。
将枚举值注入到 bean 中作为属性或构造函数参数在 Spring 中很容易实现。您实际上无需做任何事情或了解 Spring 内部(甚至不需要了解 FieldRetrievingFactoryBean
等类)。以下示例枚举显示了注入枚举值是多么容易:
-
Java
-
Kotlin
package jakarta.persistence;
public enum PersistenceContextType {
TRANSACTION,
EXTENDED
}
package jakarta.persistence
enum class PersistenceContextType {
TRANSACTION,
EXTENDED
}
现在考虑以下 PersistenceContextType
类型的 setter 和相应的 bean 定义:
-
Java
-
Kotlin
package example;
public class Client {
private PersistenceContextType persistenceContextType;
public void setPersistenceContextType(PersistenceContextType type) {
this.persistenceContextType = type;
}
}
package example
class Client {
lateinit var persistenceContextType: PersistenceContextType
}
<bean class="example.Client">
<property name="persistenceContextType" value="TRANSACTION"/>
</bean>
使用 <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
)创建一个名为 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"/>
<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>
在以下示例中,路径是针对内部 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。
使用 <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
)实例化一个 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"/>
使用 <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
实现。
使用 <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
实现。
使用 <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
实现。
aop
模式
aop
标签用于配置 Spring 中的所有 AOP 相关内容,包括 Spring 自己的基于代理的 AOP 框架以及 Spring 与 AspectJ AOP 框架的集成。这些标签在 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>
context
模式
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 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 资源位置)进行解析。此元素是一个便利机制,可为您设置 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 的
|
使用 <component-scan/>
此元素在 基于注解的容器配置 一节中进行了详细介绍。
使用 <load-time-weaver/>
此元素在 Spring 框架中 AspectJ 的加载时织入 一节中进行了详细介绍。
使用 <spring-configured/>
此元素在 使用 AspectJ 通过 Spring 依赖注入领域对象 一节中进行了详细介绍。
使用 <mbean-export/>
此元素在 配置基于注解的 MBean 导出 一节中进行了详细介绍。
Beans 模式
最后但同样重要的是,我们有 beans
模式中的元素。这些元素自框架诞生之初就存在于 Spring 中。这里不显示 beans
模式中各种元素的示例,因为它们在 依赖关系和详细配置(以及实际上整个 章节)中已经得到了全面介绍。
请注意,您可以向 <bean/>
XML 定义添加零个或多个键值对。这些额外元数据的作用(如果有的话)完全取决于您自己的自定义逻辑(因此通常只有在您编写自己的自定义元素时才有用,如附录 XML 模式编写 中所述)。
以下示例显示了 <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"/> [id="CO1-1"]1
<property name="name" value="Rick"/>
</bean>
</beans>
<1> 这是示例 `meta` 元素
在前一个示例中,您可以假设存在一些逻辑,它会消费 bean 定义并设置使用提供的元数据的一些缓存基础设施。