如上一节所述,您可以将bean属性和构造函数参数定义为对其他受管Bean(协作者)的引用,也可以定义为inline。Spring的基于XML的配置元数据支持其<property />和<constructor-arg />元素中的子元素类型。
Straight values (primitives, Strings, and so on)
<property />元素的value属性将一个属性或构造函数参数指定为人类可读的字符串表示形式。Spring的转换服务用于将这些值从String转换为实际的属性或参数类型。
<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="masterkaoli"/>
</bean>
以下示例使用p命名空间进行更简洁的XML配置。
<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
http://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="masterkaoli"/>
</beans>
前面的XML更简洁;但是,在运行时而不是设计时发现错字,除非您在创建bean定义时使用支持自动属性完成的IDE(如IntelliJ IDEA或Spring Tool Suite(STS))。
您还可以将java.util.Properties实例配置为:
<bean id="mappings"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- 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容器通过使用JavaBeans PropertyEditor机制将<value />元素内的文本转换为java.util.Properties实例。这是一个很好的捷径,而且是Spring团队赞成在value属性样式中使用嵌套的<value />元素的几个地方之一。
The idref element
idref元素只是将容器中另一个bean的id(字符串值 - 不是引用)传递给<constructor-arg />或<property />元素的方法。
<bean id="theTargetBean" class="..."/>
<bean id="theClientBean" class="...">
<property name="targetName">
<idref bean="theTargetBean"/>
</property>
</bean>
上述bean定义片段与以下代码片段完全相同(在运行时):
<bean id="theTargetBean" class="..." />
<bean id="client" class="...">
<property name="targetName" value="theTargetBean"/>
</bean>
第一种形式优于第二种形式,因为使用idref标签允许容器在部署时验证引用的命名bean实际存在。在第二个变体中,不会对传递给客户端bean的targetName属性的值执行验证。客户端bean实际上被实例化时,才会发现错字(最可能是致命(fatal)的结果)。如果客户端bean是原型bean( prototype bean),则此错误和生成的异常只能在容器部署后才能被发现。
在4.0 beans xsd中,idref元素上的local属性不再受支持,因为它不再提供超过常规bean引用的值。在升级到4.0模式时,只需将您现有的idref本地引用更改为idref bean。
一个常见的地方(至少在Spring 2.0之前的版本中),其中<idref />元素带来价值是在ProxyFactoryBean bean定义中配置AOP拦截器。指定拦截器名称时使用<idref />元素可防止拼写错误。
References to other beans (collaborators)
ref元素是<constructor-arg />或<property />定义元素中的最后一个元素。在这里,您可以将bean的指定属性的值设置为对由容器管理的另一个bean(协作者)的引用。引用的bean是其属性将被设置的bean的依赖关系,并且在设置属性之前根据需要初始化它。(如果协作者( collaborator)是单例bean,则可以由容器初始化它。)所有references最终都是对另一个对象的引用。范围和验证取决于是否通过bean,本地或父属性指定其他对象的id / name。通过<ref />标签的bean属性指定目标bean是最通用的形式,允许创建对同一容器或父容器中任何bean的引用,而不管它们是否在同一个XML文件中。bean属性的值可能与目标bean的id属性相同,或者与目标bean的name属性中的值之一相同。通过父属性指定目标bean创建对当前容器的父容器中的bean的引用。
<ref bean="someBean"/>
父属性的值可能与目标bean的id属性或目标bean的name属性中的值之一相同,目标bean必须位于当前bean的父容器中。您使用此bean参考变体主要是在具有容器层次结构时,并且想要使用与父bean具有相同名称的代理将现有bean包装在父容器中。
<!-- in the parent context -->
<bean id="accountService" class="com.foo.SimpleAccountService">
<!-- insert dependencies as required as 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>
![]() |
4.0 bean xsd中不再支持ref元素上的local属性,因为它不再提供超过常规bean引用的值。在升级到4.0模式时,只需将现有的ref参考引用改为ref bean。 |
Inner beans
<property />或<constructor-arg />元素中的<bean />元素定义了一个所谓的内部bean。
<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或名称;如果指定,容器不使用这样的值作为标识符。容器也会忽略创建的范围标志:内部bean总是匿名的,它们总是使用外部bean创建的。将内部bean注入到除了封闭bean之外的协作bean中,或者独立访问它们是不可能的。
Collections
在<list />,<set />,<map />和<props />元素中,您可以分别设置Java集合类型列表,集合,映射和属性的属性和参数。