对于最新的稳定版本,请使用 Spring Framework 6.2.0spring-doc.cadn.net.cn

依赖项和配置详细信息

上一节所述,您可以定义 bean properties 和构造函数参数作为对其他托管 bean (协作者) 的引用 或作为内联定义的值。Spring 基于 XML 的配置元数据支持 子元素类型中的<property/><constructor-arg/>元素 目的。spring-doc.cadn.net.cn

Straight 值(Primitives、Strings 等)

value属性的<property/>元素指定属性或构造函数 参数作为人类可读的字符串表示形式。Spring 的转换服务用于转换这些 值String设置为属性或参数的实际类型。 以下示例显示了正在设置的各种值:spring-doc.cadn.net.cn

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
	<!-- results in a setDriverClassName(String) call -->
	<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
	<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
	<property name="username" value="root"/>
	<property name="password" value="misterkaoli"/>
</bean>

以下示例使用 p-namespace 以获得更简洁的 XML 配置:spring-doc.cadn.net.cn

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	https://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close"
		p:driverClassName="com.mysql.jdbc.Driver"
		p:url="jdbc:mysql://localhost:3306/mydb"
		p:username="root"
		p:password="misterkaoli"/>

</beans>

前面的 XML 更简洁。但是,拼写错误是在运行时发现的,而不是 设计时,除非您使用 IDE(例如 IntelliJ IDEASpring Tools for Eclipse) 支持在创建 Bean 定义时自动完成属性。这样的 IDE 强烈建议您提供帮助。spring-doc.cadn.net.cn

您还可以配置java.util.Properties实例,如下所示:spring-doc.cadn.net.cn

<bean id="mappings"
	class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">

	<!-- typed as a java.util.Properties -->
	<property name="properties">
		<value>
			jdbc.driver.className=com.mysql.jdbc.Driver
			jdbc.url=jdbc:mysql://localhost:3306/mydb
		</value>
	</property>
</bean>

Spring 容器将<value/>元素转换为java.util.Properties实例PropertyEditor机制。这 是一个不错的快捷方式,并且是 Spring 团队确实喜欢使用 嵌套的<value/>元素覆盖在value属性样式。spring-doc.cadn.net.cn

idref元素

idref元素只是一种防错的方式,用于将id(字符串值 - not 引用)附加到容器中另一个 bean 的<constructor-arg/><property/>元素。以下示例演示如何使用它:spring-doc.cadn.net.cn

<bean id="theTargetBean" class="..."/>

<bean id="theClientBean" class="...">
	<property name="targetName">
		<idref bean="theTargetBean"/>
	</property>
</bean>

前面的 bean 定义代码片段完全等价(在运行时)用于 以下代码段:spring-doc.cadn.net.cn

<bean id="theTargetBean" class="..." />

<bean id="theClientBean" class="...">
	<property name="targetName" ref="theTargetBean"/>
</bean>

第一种形式比第二种形式更可取,因为使用idref标签允许 容器在部署时验证引用的名为 Bean 的实际 存在。在第二个变体中,不对传递的值执行验证 到targetName属性的client豆。拼写错误仅被发现(大多数 可能致命的结果),当clientbean 实际上是实例化的。如果clientbean 是一个原型 bean,这个拼写错误和结果异常 只有在部署容器很久之后才能被发现。spring-doc.cadn.net.cn

local属性idref元素在 4.0 bean 中不再受支持 XSD 的 ID,因为它没有提供比常规bean参考。改变 您现有的idref local参考资料idref bean升级到 4.0 架构时。

一个常见的地方(至少在 Spring 2.0 之前的版本中),其中<idref/>元素 带来的值是在 AOP 拦截器的配置中ProxyFactoryBeanbean 定义。用<idref/>元素,当您指定 拦截器 名称 可防止您拼写错误的拦截器 ID。spring-doc.cadn.net.cn

对其他 Bean 的引用(协作者)

ref元素是<constructor-arg/><property/>definition 元素。在这里,您将 bean 的指定属性的值设置为 对容器管理的另一个 Bean(协作者)的引用。引用的 Bean 是要设置其属性的 Bean 的依赖项,并且按需初始化 根据需要。(如果协作者是单例 bean,则它可能会 已由容器初始化。所有引用最终都是对 另一个对象。范围界定和验证取决于您是指定 other 对象通过beanparent属性。spring-doc.cadn.net.cn

通过bean属性的<ref/>标签是最 general 形式,并允许创建对同一容器中任何 bean 的引用,或者 父容器,无论它是否在同一个 XML 文件中。的bean属性可能与id属性或相同 作为name目标 Bean 的属性。以下示例 演示如何使用ref元素:spring-doc.cadn.net.cn

<ref bean="someBean"/>

通过parentattribute 创建对 Bean 的引用 即在当前容器的父容器中。的parent属性可以与id目标 Bean 的属性或 值中的name目标 Bean 的属性。目标 Bean 必须位于 当前容器的父容器。您应该主要使用此 bean 引用变体 当您具有容器层次结构并且希望将现有 bean 包装在父 bean 中时 容器,其代理与父 Bean 同名。以下一对 清单 显示了如何使用parent属性:spring-doc.cadn.net.cn

<!-- in the parent context -->
<bean id="accountService" class="com.something.SimpleAccountService">
	<!-- insert dependencies as required here -->
</bean>
<!-- in the child (descendant) context -->
<bean id="accountService" <!-- bean name is the same as the parent bean -->
	class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="target">
		<ref parent="accountService"/> <!-- notice how we refer to the parent bean -->
	</property>
	<!-- insert other configuration and dependencies as required here -->
</bean>
local属性ref元素在 4.0 bean 中不再受支持 XSD 的 ID,因为它没有提供比常规bean参考。改变 您现有的ref local参考资料ref bean升级到 4.0 架构时。

内部 Bean

一个<bean/>元素中的<property/><constructor-arg/>元素定义一个 inner bean,如下例所示:spring-doc.cadn.net.cn

<bean id="outer" class="...">
	<!-- instead of using a reference to a target bean, simply define the target bean inline -->
	<property name="target">
		<bean class="com.example.Person"> <!-- this is the inner bean -->
			<property name="name" value="Fiona Apple"/>
			<property name="age" value="25"/>
		</bean>
	</property>
</bean>

内部 Bean 定义不需要定义的 ID 或名称。如果指定,则容器 不使用此类值作为标识符。容器还会忽略scope标记 创建,因为内部 bean 始终是匿名的,并且总是使用外部 bean 创建 豆。无法独立访问内部 bean 或将它们注入 将 bean 协作到封闭 bean 中。spring-doc.cadn.net.cn

作为一种极端情况,可以从自定义范围接收销毁回调 — 例如,对于包含在单例 bean 中的请求范围的内部 bean。创作 的 Bean 实例绑定到其包含的 Bean,但销毁回调允许它 参与请求范围的生命周期。这不是常见情况。内豆 通常只是共享其包含的 bean 的 scope。spring-doc.cadn.net.cn

收集

<list/>,<set/>,<map/><props/>元素设置属性 和 Java 的参数Collection类型List,Set,MapProperties, 分别。以下示例显示了如何使用它们:spring-doc.cadn.net.cn

<bean id="moreComplexObject" class="example.ComplexObject">
	<!-- results in a setAdminEmails(java.util.Properties) call -->
	<property name="adminEmails">
		<props>
			<prop key="administrator">[email protected]</prop>
			<prop key="support">[email protected]</prop>
			<prop key="development">[email protected]</prop>
		</props>
	</property>
	<!-- results in a setSomeList(java.util.List) call -->
	<property name="someList">
		<list>
			<value>a list element followed by a reference</value>
			<ref bean="myDataSource" />
		</list>
	</property>
	<!-- results in a setSomeMap(java.util.Map) call -->
	<property name="someMap">
		<map>
			<entry key="an entry" value="just some string"/>
			<entry key="a ref" value-ref="myDataSource"/>
		</map>
	</property>
	<!-- results in a setSomeSet(java.util.Set) call -->
	<property name="someSet">
		<set>
			<value>just some string</value>
			<ref bean="myDataSource" />
		</set>
	</property>
</bean>

map 键或值的值,或者一个 set 值,也可以是 以下元素:spring-doc.cadn.net.cn

bean | ref | idref | list | set | map | props | value | null

集合合并

Spring 容器还支持合并集合。应用程序 developer 可以定义父级<list/>,<map/>,<set/><props/>元素 并有孩子<list/>,<map/>,<set/><props/>元素继承和 覆盖父集合中的值。也就是说,子集合的值为 将父集合和子集合的元素与子集合的 collection 元素覆盖父集合中指定的值。spring-doc.cadn.net.cn

本节关于合并讨论了父子 Bean 机制。不熟悉的读者 with 父 Bean 和 Child Bean 定义可能希望在继续之前阅读相关部分spring-doc.cadn.net.cn

以下示例演示了集合合并:spring-doc.cadn.net.cn

<beans>
	<bean id="parent" abstract="true" class="example.ComplexObject">
		<property name="adminEmails">
			<props>
				<prop key="administrator">[email protected]</prop>
				<prop key="support">[email protected]</prop>
			</props>
		</property>
	</bean>
	<bean id="child" parent="parent">
		<property name="adminEmails">
			<!-- the merge is specified on the child collection definition -->
			<props merge="true">
				<prop key="sales">[email protected]</prop>
				<prop key="support">[email protected]</prop>
			</props>
		</property>
	</bean>
<beans>

请注意merge=true属性<props/>元素的adminEmails属性的childbean 定义。当childBean 已解析 并由容器实例化,则生成的实例具有adminEmails Properties集合,其中包含合并子adminEmailscollection 替换为父级的adminEmails收集。以下清单 显示结果:spring-doc.cadn.net.cn

孩子Propertiescollection 的值集继承了 父母<props/>的 API 的supportvalue 覆盖 父集合。spring-doc.cadn.net.cn

此合并行为类似于<list/>,<map/><set/>集合类型。在<list/>元素、语义 与List集合类型(即ordered值的集合)的 Collection。parent的值位于所有child列表的 值。在Map,SetProperties集合类型,无排序 存在。因此,对于作为基础的集合类型,没有排序语义 关联的Map,SetPropertiesimplementation types 中,容器 内部使用。spring-doc.cadn.net.cn

集合合并的限制

您不能合并不同的集合类型(例如Map以及List).如果你 请尝试这样做,适当的Exception被抛出。这mergeattribute 必须为 在较低的继承子定义上指定。指定merge属性 父集合定义是冗余的,不会导致所需的合并。spring-doc.cadn.net.cn

强类型集合

由于 Java 对泛型类型的支持,您可以使用强类型集合。 也就是说,可以声明Collection类型,使其只能包含 (例如)String元素。如果您使用 Spring 依赖注入 强类型Collection添加到 bean 中,您可以利用 Spring 的 type-conversion 支持,以便Collection实例在添加到Collection. 下面的 Java 类和 bean 定义显示了如何做到这一点:spring-doc.cadn.net.cn

public class SomeClass {

	private Map<String, Float> accounts;

	public void setAccounts(Map<String, Float> accounts) {
		this.accounts = accounts;
	}
}
class SomeClass {
	lateinit var accounts: Map<String, Float>
}
<beans>
	<bean id="something" class="x.y.SomeClass">
		<property name="accounts">
			<map>
				<entry key="one" value="9.99"/>
				<entry key="two" value="2.75"/>
				<entry key="six" value="3.99"/>
			</map>
		</property>
	</bean>
</beans>

accounts属性的somethingbean 准备注入,泛型 有关强类型的元素类型的信息Map<String, Float>是 由 Reflection 提供。因此,Spring 的类型转换基础结构识别 各种 value 元素为 类型Float和字符串值 (9.99,2.753.99) 转换为实际的Float类型。spring-doc.cadn.net.cn

Null 和空字符串值

Spring 将 properties 等的空参数视为空Strings.这 以下基于 XML 的配置元数据代码段将email属性设置为空的String值 (“”)。spring-doc.cadn.net.cn

<bean class="ExampleBean">
	<property name="email" value=""/>
</bean>

前面的示例等效于以下 Java 代码:spring-doc.cadn.net.cn

exampleBean.setEmail("");
exampleBean.email = ""

<null/>元素手柄null值。下面的清单显示了一个示例:spring-doc.cadn.net.cn

<bean class="ExampleBean">
	<property name="email">
		<null/>
	</property>
</bean>

上述配置等效于以下 Java 代码:spring-doc.cadn.net.cn

exampleBean.setEmail(null);
exampleBean.email = null

带有 p 命名空间的 XML 快捷方式

p 命名空间允许您使用bean元素的属性(而不是嵌套的<property/>元素)来描述您的属性值、协作 Bean 和/或两者。spring-doc.cadn.net.cn

Spring 支持带有命名空间的可扩展配置格式, 它们基于 XML 架构定义。这beans配置格式 本章在 XML Schema 文档中定义。但是,未定义 p 命名空间 在 XSD 文件中,并且仅存在于 Spring 的核心中。spring-doc.cadn.net.cn

以下示例显示了两个 XML 代码段(第一个使用 标准 XML 格式,第二个使用 p-namespace),它们解析为相同的结果:spring-doc.cadn.net.cn

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean name="classic" class="com.example.ExampleBean">
		<property name="email" value="[email protected]"/>
	</bean>

	<bean name="p-namespace" class="com.example.ExampleBean"
		p:email="[email protected]"/>
</beans>

该示例显示了 p 命名空间中名为email在 bean 定义中。 这告诉 Spring 包含一个属性声明。如前所述, p-namespace 没有 schema 定义,因此您可以设置属性的名称 添加到属性名称。spring-doc.cadn.net.cn

下一个示例包括另外两个 bean 定义,这两个定义都引用了 另一个 bean:spring-doc.cadn.net.cn

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean name="john-classic" class="com.example.Person">
		<property name="name" value="John Doe"/>
		<property name="spouse" ref="jane"/>
	</bean>

	<bean name="john-modern"
		class="com.example.Person"
		p:name="John Doe"
		p:spouse-ref="jane"/>

	<bean name="jane" class="com.example.Person">
		<property name="name" value="Jane Doe"/>
	</bean>
</beans>

此示例不仅包括使用 p-namespace 的属性值 但也使用特殊格式来声明属性引用。而第一个 bean 定义用途<property name="spouse" ref="jane"/>从 Bean 创建引用john到 Beanjane,第二个 bean 定义使用p:spouse-ref="jane"作为 属性来执行完全相同的作。在这种情况下,spouse是属性名称, 而-refpart 表示这不是一个直接的值,而是一个 引用另一个 bean。spring-doc.cadn.net.cn

p 命名空间不如标准 XML 格式灵活。例如,格式 用于声明属性引用与以Ref,而 标准 XML 格式则不需要。我们建议您仔细选择方法,并 将此内容传达给您的团队成员,以避免生成使用全部 同时有三种方法。

带有 c-namespace 的 XML 快捷方式

类似于 Spring 中引入的带有 p-namespace 的 XML Shortcut、c-namespace 3.1 中,允许内联属性来配置构造函数参数,而不是 然后嵌套constructor-arg元素。spring-doc.cadn.net.cn

以下示例使用c:namespace 执行与 from Constructor-based Dependency Injection 相同的作:spring-doc.cadn.net.cn

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:c="http://www.springframework.org/schema/c"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="beanTwo" class="x.y.ThingTwo"/>
	<bean id="beanThree" class="x.y.ThingThree"/>

	<!-- traditional declaration with optional argument names -->
	<bean id="beanOne" class="x.y.ThingOne">
		<constructor-arg name="thingTwo" ref="beanTwo"/>
		<constructor-arg name="thingThree" ref="beanThree"/>
		<constructor-arg name="email" value="[email protected]"/>
	</bean>

	<!-- c-namespace declaration with argument names -->
	<bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"
		c:thingThree-ref="beanThree" c:email="[email protected]"/>

</beans>

c:namespace 使用与p:one(尾随的-ref为 Bean 引用)来按名称设置构造函数参数。同样地 它需要在 XML 文件中声明,即使它未在 XSD 架构中定义 (它存在于 Spring 核心中)。spring-doc.cadn.net.cn

对于构造函数参数名称不可用的极少数情况(通常如果 字节码是在没有-parameters标志),则可以回退到 ARGUMENT 索引,如下所示:spring-doc.cadn.net.cn

<!-- c-namespace index declaration -->
<bean id="beanOne" class="x.y.ThingOne" c:_0-ref="beanTwo" c:_1-ref="beanThree"
	c:_2="[email protected]"/>
由于 XML 语法的原因,索引表示法需要存在前导 , 因为 XML 属性名称不能以数字开头(即使某些 IDE 允许)。 相应的索引表示法也可用于_<constructor-arg>元素,但 不常用,因为 plain order of declaration 通常就足够了。

在实践中,构造函数解析机制在匹配方面非常有效 参数,因此,除非你真的需要,否则我们建议使用 name 表示法 在整个配置中。spring-doc.cadn.net.cn

复合属性名称

在设置 Bean 属性时,可以使用复合或嵌套属性名称,只要 除最终属性名称之外,路径的所有组件都不是null.考虑一下 遵循 bean 定义:spring-doc.cadn.net.cn

<bean id="something" class="things.ThingOne">
	<property name="fred.bob.sammy" value="123" />
</bean>

somethingBean 的fred属性,该属性具有bob属性,该属性具有sammyproperty 和最终的sammy属性设置为123.为了 this 要起作用,则fred的属性somethingbob的属性fred莫 是null在 bean 构造之后。否则,一个NullPointerException被抛出。spring-doc.cadn.net.cn