7.5.8 注入集合值 如果需要调用形参类型为集合的setter
方法,或调用形参类型为集合的构造器,则可使用集合元素<list>
、<set>
、<map>
和<props>
分别来设置类型为List
、Set
、Map
和Properties
的集合参数值。 下面先定义一个包含大量集合属性的Java
类,配置文件将会通过上面那些元素来为这些集合属性设置属性值。看如下Java
类的代码。
项目结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5 \collection └─src \ ├─beans.xml ├─lee \ │ └─BeanTest.java └─org \ └─crazyit \ └─app \ └─service \ ├─Axe.java ├─impl \ │ ├─Chinese.java │ ├─SteelAxe.java │ └─StoneAxe.java └─Person.java
Chinese.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 package org.crazyit.app.service.impl;import java.util.*;import org.crazyit.app.service.*;public class Chinese implements Person { private List<String> schools; private Map scores; private Map<String , Axe> phaseAxes; private Properties health; private Set axes; private String[] books; public Chinese () { System.out.println("Spring实例化主调bean:Chinese实例..." ); } public void setSchools (List schools) { this .schools = schools; } public void setScores (Map scores) { this .scores = scores; } public void setPhaseAxes (Map<String , Axe> phaseAxes) { this .phaseAxes = phaseAxes; } public void setHealth (Properties health) { this .health = health; } public void setAxes (Set axes) { this .axes = axes; } public void setBooks (String[] books) { this .books = books; } public void test () { System.out.println(schools); System.out.println(scores); System.out.println(phaseAxes); System.out.println(health); System.out.println(axes); System.out.println(java.util.Arrays.toString(books)); } }
在上面的Chinese
类中定义了6个集合类型的成员变量。下面分别为<property>
元素增加<list>
、<set>
、<map>
和<props>
子元素来配置这些集合类型的参数值。 下面是Spring
的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 <?xml version="1.0" encoding="GBK" ?> <beans xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns ="http://www.springframework.org/schema/beans" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean id ="stoneAxe" class ="org.crazyit.app.service.impl.StoneAxe" /> <bean id ="steelAxe" class ="org.crazyit.app.service.impl.SteelAxe" /> <bean id ="chinese" class ="org.crazyit.app.service.impl.Chinese" > <property name ="schools" > <list > <value > 小学</value > <value > 中学</value > <value > 大学</value > </list > </property > <property name ="scores" > <map > <entry key ="数学" value ="87" /> <entry key ="英语" value ="89" /> <entry key ="语文" value ="82" /> </map > </property > <property name ="phaseAxes" > <map > <entry key ="原始社会" value-ref ="stoneAxe" /> <entry key ="农业社会" value-ref ="steelAxe" /> </map > </property > <property name ="health" > <props > <prop key ="血压" > 正常</prop > <prop key ="身高" > 175</prop > </props > </property > <property name ="axes" > <set > <value > 普通的字符串</value > <bean class ="org.crazyit.app.service.impl.SteelAxe" /> <ref bean ="stoneAxe" /> <list > <value > 20</value > <set > <value type ="int" > 30</value > </set > </list > </set > </property > <property name ="books" > <list > <value > 疯狂Java讲义</value > <value > 疯狂Android讲义</value > <value > 轻量级Java EE企业应用实战</value > </list > </property > </bean > </beans >
上面的代码是配置集合类型的参数值的关键代码,从配置文件可以看出, Spring
对List
集合和数组
的处理是一样的,都用<list>
元素来配置 。 当使用<list>
、<set>
、<map>
.等元素配置集合类型的参数值时,还需要配置集合元素。由于集合元素又可以是基本类型值、引用容器中的其他Bean
、嵌套Bean
或集合属性等,所以<list>
、<key>
和<set>
元素又可接受如下子元素:
<value>
:指定集合元素是基本数据类型值或字符串类型值。
<ref>
:指定集合元素是容器中的另一个Bean
实例。
<bean>
:指定集合元素是一个嵌套Bean
。
<list>
、<set>
、<map>
及<props>
:指定集合元素又是集合。
props元素说明 <props>
元素用于配置Properties
类型的参数值, Properties
类型是一种特殊的类型,其key
和value
能是字符串,故Spring
配置Properties
类型的参数值比较简单:每个key-value
对只要分别给出key
和value
就足够了;因为key
和value
都是字符串类型,所以使用如下格式的<prop>
元素就够了:
1 2 3 4 <props > <prop key ="血压" > 正常</prop > <prop key ="身高" > 175</prop > </props >
简化写法 Spring
还提供了一个简化语法来支持Properties
形参的setter
方法,例如如下配置片段:
1 2 3 4 5 6 <property name ="health" > <value > pressure=normal height=175 </value > </property >
简化写法中不能出现中文 上面这种配置方式同样配置了两组属性,但这种配置语法有一个很大的限制:属性名、属性值都只能是英文或数字,不可出现中文!
map元素说明 当使用<map>
元素配置Map
参数值时比较复杂,因为Map
集合的每个元素由key
、 value
两个部分组成,所以配置文件中的每个<entry>
配置一组key-value
对,其中<entry>
元素支持如下4个属性。
<entry>
元素的属性
描述
key
如果Map key
是基本类型值或字符串,则可使用该属性来指定Map key
key-ref
如果Map key
是容器中的另一个Bean
实例,则可使用该属性指定容器中其他Bean
的id
value
如果Map value
是基本类型值或字符串,则可使用该属性来指定Map value
;
value-ref
如果Map value
是容器中的另一个Bean
实例,则可使用该属性指定容器中其他Bean
的id
由于Map
集合的key
、 value
都可以是基本类型值
、引用
容器中的其他Bean
、嵌套Bean
或集合属性等,所以也可以采用比较传统、比较臃肿的写法。例如,将上面关于scores
属性的配置写成如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <property name ="scores" > <map > <entry > <key > <value > 数学</value > </key > <value > 87</value > </entry > <entry > <key > <value > 英语</value > </key > <value > 89</value > </entry > <entry > <key > <value > 语文</value > </key > <value > 82</value > </entry > </map > </property >
从上面配置可以看出,<key>
元素专门用于配置Map
集合的key-value
对的key
,又由于Map key
又可能是基本类型、引用容器中已有的Bean
、嵌套Bean
、集合等,因此<key>
的子元素又可以是value
、ref
、bean
、list
、set
、map
和props
等元素。
集合的合并 从Spring2.0
开始, Spring loC
容器将支持集合的合并,子Bean
中的集合属性值可以从其父Bean
的集合属性继承
和覆盖
而来。也就是说,子Bean
的集合属性的最终值是父Bean
、子Bean
合并后的最终结果,而且子Bean
集合中的元素可以覆盖父Bean
集合中对应的元素 。 下面的配置片段示范了集合合并的特性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <beans > <bean id ="" parent abstract ="true" class ="example.ComplexObject" > <property name ="adminEmails" > <props > <prop key ="administrator" > administrator@crazyit.org</prop > <prop key ="suppport" > suppport@crazyit.org</prop > </props > </property > </bean > <bean id ="child" parent ="parent" > <property id ="child" name ="adminEmails" > <props merge ="true" > <prop key ="sales" > sales@crazyit.org</prop > <prop key ="support" > support@crazyit.org</prop > </props > <property > </bean > </beans >
上面的配置片段中child Bean
继承了parent Bean
,并为<props>
元素指定了merge="true"
,这将会把parent Bean
的集合属性合并到child Bean
中; 当进行合并时,由child Bean
再次配置了名为support
的属性,所以该属性将会覆盖parent Bean
中的配置定义,于是child bean
的adminEmails
属性值如下:
1 2 3 administrator=administratore@crazyit .org sales=sales@crazyit .org support=master@crazyit .org
泛型支持 从JDK1.5
以后,Java
可以使用泛型指定集合元素的类型,则Spring
可通过反射来获取集合元素的类型,这样Spring
的类型转换器也会起作用了。 例如如下Java
代码:
1 2 3 4 5 6 7 8 public class Test { private Map<string, Double> prices; public void setPrices (Map<string Double> prices) { this .prices= prices; } }
上面的prices
集合是Map
集合,且程序使用泛型限制了Map
的key
是String
,且value
是Double
,则Spring
可根据泛型信息把配置文件的集合参数值转换成相应的数据类型。例如如下配置片段:
1 2 3 4 5 6 7 8 <bean id ="test" class ="lee.Test" > <property name ="prices" > <map > <entry key ="疯狂 Android讲义" vaue ="99.0" /> <entry key ="疯狂Java讲义" value ="109.0" /> </map > </property > </bean >