正如前面提到的那样,bean的属性和构造函数参数可以被定义为其他bean的引用(合作者),或者内联定义的值。为了达到这个目的,XmlBeanFactory在property和constructor-arg元素中支持许多子元素类型。
value元素用适合人读的字符串形式指定属性或构造函数参数。正如前面提到的那样,JavaBeans的PropertyEditors被用来将这些字符串从java.lang.String类型转变为真实的属性类型或参数类型。
<beans>
<bean destroy-method="close">
<!-- results in a setDriverClassName(String) call -->
<property >
<value>com.mysql.jdbc.Driver</value>
</property>
<property >
<value>jdbc:mysql://localhost:3306/mydb</value>
</property>
<property >
<value>root</value>
</property>
</bean>
</beans>bean >
<property ><value></value></property>
</bean>
导致email属性被设置为””,同java代码:exampleBean.setEmail("")等价。而专门的<null>元素则可以用来指定一个null值,所以
<bean >
<property ><null/></property>
</bean>
同代码:exampleBean.setEmail(null)是等价的.
list, set, map, 以及 props 元素可以用来定义和设置类型 为Java的List,Set, Map, 和 Properties .
<beans>
...
<bean >
<!-- results in a setPeople(java.util.Properties) call -->
<property >
<props>
<prop key="HarryPotter">The magic property</prop>
<prop key="JerrySeinfeld">The funny property</prop>
</props>
</property>
<!-- results in a setSomeList(java.util.List) call -->
<property >
<list>
<value>a list element followed by a reference</value>
<ref bean="myDataSource"/>
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property >
<map>
<entry key="yup an entry">
<value>just some string</value>
</entry>
<entry key="yup a ref">
<ref bean="myDataSource"/>
</entry>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property >
<set>
<value>just some string</value>
<ref bean="myDataSource"/>
</set>
</property>
</bean>
</beans>
注意:Map的entry或set的value,它们的值又可以是下面元素中的任何一个:
(bean | ref | idref | list | set | map | props | value | null)
在property 元素中定义的bean元素用来定义一个内联的bean,而不是引用BeanFactory其他地方定义的bean。内联bean定义不需要任何id定义
<bean >
<!-- Instead of using a reference to target, just use an inner bean -->
<property >
<bean >
<property ><value>Tony</value></property>
<property ><value>51</value></property>
</bean>
</property>
</bean>
idref元素完全是一种简写和防止错误的方式,用来设置属性值为容器中其他bean的id 或name。
<bean >
</bean>
<bean >
<property >
<idref bean="theTargetBean"/>
</property>
</bean>
bean > </bean> <bean > <property > <value>theTargetBean</value> </property> </bean>
第一种形式比第二种形式更好的原因是:使用idref标记将会使Spring在部署的时候就验证其他的bean是否真正存在;在第二种形式中,targetName属性的类仅仅在Spring实例化这个类的时候做它自己的验证,这很可能在容器真正部署完很久之后。
另外,如果被引用的bean在同一个xml文件中而且bean的名称是bean的 id,那么就可以使用local属性。它会让XML解析器更早,在XML文档解析的时候,验证bean的名称。
<property >
<idref local="theTargetBean"/>
</property>
ref元素是最后一个能在property元素中使用的元素。它是用来设置属性值引用容器管理的其他bean(可以叫做合作者)。正如前一节提到的,拥有这些属性的bean依赖被引用的bean,被引用的bean将会在属性设置前,必要的时候需要时初始化(如果是一个singleton bean可能已经被容器初始化)。所有的引用根本上是一个指向其他对象的引用,不过有3种形式指定被引用对象的id/name,这3种不同形式决定作用域和如何处理验证。
用ref元素的bean属性指定目标bean是最常见的形式,它允许指向的bean可以在同一个BeanFactory/ApplicationContext(无论是否在同一个XML文件中)中,也可以在父BeanFactory/ApplicationContext中。bean属性的值可以同目标bean的id属性相同,也可以同目标bean的name属性中任何一个值相同。
<ref bean="someBean"/>
用local属性指定目标bean可以利用XML解析器的能力在同一个文件中验证XML id引用。local属性的值必须与目标bean的id属性一致。如果在同一个文件中没有匹配的元素,XML解析器将会产生一个错误。因此,如果目标bean在同一个XML文件中,那么使用local形式将是最好的选择(为了能够尽可能早的发现错误)。
<ref local="someBean"/>
用parent属性指定目标bean允许引用当前BeanFactory(ApplicationContext)的父BeanFactory(ApplicationContext)中的bean。parent属性的值可以同目标bean的id属性相同,也可以同目标bean的name属性中的一个值相同,而且目标bean必须在当前BeanFactory(ApplicationContext)的父BeanFactory(ApplicationContext)中。当需要用某种proxy包装一个父上下文中存在的bean(可能和父上下文中的有同样的name),所以需要原始的对象用来包装它。
<ref parent="someBean"/>