XML Schemas
此附录部分列出了与核心容器相关的 XML 架构。
The util
Schema
顾名思义,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>
Using <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>
Setting a Bean Property or Constructor Argument from a Field Value
FieldRetrievingFactoryBean
是一个[FactoryBean
]用来检索[static
]或非静态字段值。它通常用于检索[public
][static
][final
]常量,然后可用于设置另一个 Bean 的属性值或构造函数参数。
以下示例演示了如何通过使用 @ [1] 的属性 @https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html#setStaticField(java.lang.String) [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 的非静态(实例)字段,如 @https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.html [FieldRetrievingFactoryBean
] 类的 API 文档中所述。
将枚举值注入 bean 中作为属性或构造函数参数很容易在 Spring 中完成。实际上,您不必执行任何操作或了解任何有关 Spring 内部(甚至有关诸如 FieldRetrievingFactoryBean
之类的类)的信息。以下示例枚举显示了注入枚举值有多么容易:
-
Java
-
Kotlin
public enum PersistenceContextType {
TRANSACTION,
EXTENDED
}
enum class PersistenceContextType {
TRANSACTION,
EXTENDED
}
现在考虑以下 PersistenceContextType
类型和相应 bean 定义的 setter:
-
Java
-
Kotlin
public class Client {
private PersistenceContextType persistenceContextType;
public void setPersistenceContextType(PersistenceContextType type) {
this.persistenceContextType = type;
}
}
class Client {
lateinit var persistenceContextType: PersistenceContextType
}
<bean class="example.Client">
<property name="persistenceContextType" value="TRANSACTION"/>
</bean>
Using <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
)来创建 Bean(类型为 int
),称为 testBean.age
,其值等于 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
。
Using <util:property-path/>
to Set a Bean Property or Constructor Argument
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 以获取有关此特性的更多信息。
Using <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
)通过从提供的 Resource
位置加载的值来初始化 `java.util.Properties`实例)。
以下示例使用 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"/>
Using <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
实现。
Using <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
实现。
Using <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
实现。
The aop
Schema
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>
The context
Schema
context
标记处理与管道相关的 ApplicationContext
配置,即通常不是对最终用户重要的 Bean,而是像 BeanfactoryPostProcessors
一样在 Spring 中执行大量“基础”工作的 Bean。以下片段引用正确的架构,以便您可以使用 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>
Using <property-placeholder/>
该元素会替换 ${…}`占位符,这是针对特定的属性文件(作为一个 Spring resource location)来解析的。该元素是一种便利机制,它可为您设置一个 `PropertySourcesPlaceholderConfigurer
。如果您需要对特定的 `PropertySourcesPlaceholderConfigurer`设置有更多的控制权,则可以自己将其明确定义为 bean。
对于给定的应用程序,只应使用它所需的属性定义一个这样的元素。只要占位符语法不同(${…}
),则可以配置多个属性占位符。
如果您需要模块化用于替换的属性源,则不应创建多个属性占位符。相反,每个模块都应向 Environment
贡献一个 PropertySource
。或者,您可以创建自己的 PropertySourcesPlaceholderConfigurer
Bean 来收集要使用的属性。
Using <annotation-config/>
此元素激活 Spring 基础设施以检测 Bean 类中的注释:
-
Spring’s
@Configuration
model -
@Autowired
/@Inject
,@Value
, and@Lookup
-
JSR-250 的
@Resource
、@PostConstruct
和@PreDestroy
(如果有的话) -
JAX-WS 的
@WebServiceRef
和 EJB 3 的@EJB
(如果有的话) -
JPA 的
@PersistenceContext
和@PersistenceUnit
(如果有的话) -
Spring’s
@EventListener
或者,您可以选择明确激活那些注释的各个 BeanPostProcessors
。
此元素不会激活对 Spring 的 |
Using <component-scan/>
该元素在 annotation-based container configuration 一节中有详细介绍。
Using <load-time-weaver/>
该元素在关于 load-time weaving with AspectJ in the Spring Framework的部分中有详细说明。
Using <spring-configured/>
该元素在关于 using AspectJ to dependency inject domain objects with Spring的部分中有详细说明。
Using <mbean-export/>
该元素在关于 configuring annotation-based MBean export的部分中有详细说明。
The Beans Schema
最后但并非最不重要的是,我们有 `beans`模式中的元素。自框架的出现之初,这些元素就在 Spring 中出现。这里没有显示 `beans`模式中各种元素的示例,这是因为 dependencies and configuration in detail(实际上还有整个 chapter)对这些元素的介绍很全面。
请注意,可以向 <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>
1 | 这是示例 meta 元素 |
对于前面的示例,你可以假定有一些逻辑消耗 bean 定义,并设置使用提供元数据的某些缓存基础设施。