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 >
原文链接: 7.5.8 注入集合值