[以下文字摘自《Struts,Hibername,Spring集成开发宝典》一书]
在配置Bean的时候,为了设置Bean之间的依赖关系,经常要为Bean的属性或者构造方法执行参数值。为此,Spring提供了多种不同的方式,下面就在这里对配置的方法进行简单的介绍。
使用常量
在初始化Bean的时候,有时会使用常量来作为参数传递给Bean。例如,在配置数据源的时候,数据库的驱动、名称、用户名和密码等参数通常都是作为常量被写在配置文件中的。
在Spring中,是通过<value>元素来指定Bean的属性或者构造方法的常量参数值的。由于配置文件中所读取的配置信息都是java.lang.String类型的,所以在给具体的构造方法或者setter方法赋值的时候,会使用PropertyEditor来进行相应的类型转换。
一个简单的配置如下所示:
<bean id="exampleBean" class="cn.hxex.springcore.ExampleBean">
<constructor-arg type="int">
<value>15000</value>
</constructor-arg>
<constructor-arg type="java.lang.String">
<value>42</value>
</constructor-arg>
</bean>
在使用<value/>元素指定常量参数时,通常可以通过<constructor-arg/>元素的type属性来指定参数类型,避免由于类型转换错误而导致的参数混淆。
引用其它的Bean
在<constructor-arg/>或者<property/>元素内部还可以使用<ref>元素,该元素用来将Bean中指定属性的值设置为对容器中的另外一个Bean的引用。
如前所示该引用Bean将被作为依赖注入,而且在注入之前会被初始化。尽管都是另外一个对象的引用,但是通过id/name指向另外对象却有三种不同的形式,不同的形式将决定如何处理作用域及验证。
1. 通过使用<ref>元素的bean属性指定目标Bean,通过该元素可以引用同一个容器或者父容器内的任何Bean(无论是否在同一XML中)。Bean属性既可以是指定Bean的id值也可以是其name值;
<ref bean="someBean"/>
2. 使用<ref>的local属性指定目标Bean,它可以利用XML解析器来验证所引用的Bean是否在同一文件中。Local属性值必需是目标Bean的id属性值。如果在同一文件中没有找到引用的Bean,XML解析器将指出一个错误。如果目标Bean是在同一文件内,使用local方式就是最好的选择;
<ref local="someBean"/>
3. 使用<ref>的parent属性来引用当前容器的父容器中的Bean。Parent属性值既可以是目标Bean的id值,也可以是name属性值。而且目标Bean必需在当前容器的父容器中。使用parent属性的主要用途是为了能引用到与当前容器中同名的父容器中的Bean对象;
<ref parent="someBean"/>
内部Bean
所谓的内部Bean是指在一个Bean的<property/>或<constructor-arg/>元素中使用使用<bean/>定义的Bean。内部Bean定义需要有id或者name属性,即使指定id或name属性也将被容器忽略。
换句话说,内部Bean就相当于方法中定义的临时变量。它只能被本Bean所使用,而不能被任何外部Bean所使用。内部Bean配置方法如下:
<bean id="outer" class="...">
<property name="targe">
<bean class="com.mycompany.Person"><!-- this is the inner bean -->
<property name="name" value="Fiona Apple"/>
<property name="age" value="25"/>
</bean>
</property>
</bean>
为集合类属性赋值
Spring的IoC容器为Bean的集合类属性单独定义了赋值元素。开发人员可以通过<list/>、<set/>、<props/>元素定义和设置与Java Collection类型对应的List、Set、Map及Properties的值。
下面就通过几个简单的实例来了解一下如何为集合类属性赋值。
Ø java.util.List
<property name="someList">
<list>
<value>a list element followed by a reference</value>
<ref bean="myDataSource"/>
</list>
</property>
在<list/>元素内部可以使用前面所介绍的任意方法来并列指定List所包含的对象。在Bean的初始化时,会调用该Bean的setSomeList(List list)方法来进行依赖对象的注入操作。
Ø java.util.Properties
Properties类型的bean属性是通过<props/>元素来进行初始化的,而其它内部的每一个键-值对的定义则是通过<prop/>元素来进行配置的,配置的示例如下所示:
<properties name="adminEmails">
<props>
<prop key="admin">admin@someCompany.org</prop>
<prop key="support">support@someCompany.org</prop>
<prop key="development">development@someCompany.org</prop>
</props>
</properties>
Ø java.util.Map
Map类型的属性的初始化是通过<map/>元素来进行定义的。与Properties配置不同的是,每一个键-值对都需要放置在<entry>元素中,而且Map的键是通过<key>来进行定义的,值则可以使用前面所定义的任意方法来进行初始化。一个简单的配置示例如下:
<property name="somaMap">
<map>
<entry>
<key><value>yup an entry</value></key>
<value>just some string</value>
</entry>
<entry>
<key><value>yup a ref</value></key>
<ref bean="myDataSource"/>
</entry>
</map>
</property>
通过上面的代码可以看到,Spring的IoC容器对集合类型的注入提供了灵活的方法和多样性的方式。对于Map的键或者值以及可以使用的元素类型包括:bean、ref、idrey、list、set、map、props、value、null。
空值的处理
Spring的IoC容器定义了<null/>元素来处理空值,Spring会把属性的空参数当作空字符串来处理。一下的xml片段将email属性设为了空字符串。
<bean class="ExampleBean">
<property name="email"><value></value></property>
</bean>
这等同于Java:exampleBean.setEmail(“”).
<bean class="ExampleBean">
<property name="email"><null/></property>
</bean>
上述的配置等同于Java代码:exampleBean.setEmail(null);