2.3.3 捆绑集合
到了现在,介绍了spring配置基本类型(通过value)和其他类(通过ref)但value和ref只有在你的属性是单一的时候才有效。那么当属性是复数(就是集合)时spring怎么做呢?
Spring提供了4个类型的集合配置元素。参看2.3表
<list>和<set>当属性是array或者是一些java.util.Collection时候非常有用。下面会看到,实际实现的用来定义属性的collection,跟使用<list>还是<set>没有任何关系。两个元素都可以不经修改的使用在任何collection上。
对于<map><props>,对应是java.util.Map和java.util.Properties。这些都是值键对于的一对一对的。唯一两个不同就是props要求值键都是String。Map则没有要求。
下面是在spring中捆绑collection,Hank现在来到了SpringIdel舞台。他是一个人的乐队,跟kenny一样,他能够演奏多种乐器,不过hank是同时演奏。Hank的代码如下:
package com.springinaction.springidol;
import java.util.Collection;
public class OneManBand implements Performer {
private Collection<Instrument> instruments;
public OneManBand() {}
public void perform() throws PerformanceException {
for(Instrument instrument : instruments){
instrument.play();
}
}
public void setInstruments(Collection<Instrument> instruments) {
this.instruments = instruments;
}
}
程序中,当OnManBand执行perform方法的时候对collection进行遍历。这里最重要的是instrutment的注入是通过setter方法。看看Spring怎么支持这个collection。
Lists和Arrays
Hank要使用乐器,用list来提供给他
<bean id="hank" class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<list>
<ref bean="guitar"/>
<ref bean="cymbal"/>
<ref bean="harmonica"/>
</list>
</property>
</bean>
<list>元素包含1个或多个值。<ref>用来指向在SpringContext里的其它bean的实例,配置了hank可以弹奏guitar,cymbal,harmonica。这里可以使用其它Spring的赋值的元素,比如<bean>,<value>甚至<null/>。另外,list可以包含另外一个list,多维概念。
在OneManBand类的代码中,instruments使用的是jdk1.5的java.util.Collection。但<List>用来工作在那些的属性,它们是实现Collection或者是一个数组。就是说,<list>在以下的代码上照常工作
java.util.List<Instrument> instruments;
Instrument[] insruments;
Sets
<list>元素更关心的是Spring如何处理这些collection,而不是它的类型。你可以在用到List的地方改用set。<set>有<list>没有的好处:保证每个元素唯一。不一样的元素会被忽略。
跟<list>一样,<set>的元素类型也是collection和array。
Maps
当OneManBand执行时,每种乐器的声音在perform方法中被打印出来。但我们想看到每个音符是哪个乐器弹奏的,代码需要修改一下:
package com.springinaction.springidol;
import java.util.Map;
public class OneManBand implements Performer {
private Map<String,Instrument> instruments;
public OneManBand() {}
public void perform() throws PerformanceException {
for(String key : instruments.keySet()){
System.out.println(key + " : ");
Instrument instrument = instruments.get(key);
instrument.play();
}
}
public void setInstruments(Map<String,Instrument> instruments) {
this.instruments = instruments;
}
}
这个代码中,instruments是由键值对组成的,在xml文件中使用下面的定义:
<bean id="hank" class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<map>
<entry key="GUITAR" value-ref="guitar"/>
<entry key="CYMBAL" value-ref="cymbal"/>
<entry key="HARMONICA" value-ref="harmonica"/>
</map>
</property>
</bean>
<map>元素定义了一个map类型,每一个entry元素定义了map的一个成员。上个例子,key定义了键,value-ref定义了引用的bean的id。
下图是entry里面的元素的含义。
<map>是唯一一个能把不止是String的类型插入的键值对的方法。下面介绍Props。
Props
如果键值都是String,那么就要用到java.util.Properties类了。现在把OneManBand修改一下:
package com.springinaction.springidol;
import java.util.Iterator;
import java.util.Properties;
public class OneManBand implements Performer {
private Properties instruments;
public OneManBand() {}
public void perform() throws PerformanceException {
for (Iterator iter = instruments.keySet().iterator(); iter.hasNext();) {
String key = (String)iter.next();
System.out.println(key + " : " + instruments.getProperty(key));
}
}
public void setInstruments(Properties instruments) {
this.instruments = instruments;
}
}
Xml中做如下修改
<bean id="hank" class="com.springinaction.springidol.OneManBand">
<property name="instruments">
<props>
<prop key="GUITAR">STUM STUM STUM</prop>
<prop key="CYMBAL">CRASH CRASH CRASH</prop>
<prop key="HARMONICA">HUM HUM HUM</prop>
</props>
</property>
</bean>
This is easy to understand the code, it’s not necessary to talk about it.
有些可能有些混淆,看一下
l <property>是向bean注入一个值
l <props>是Properties定义的一个元素
l <prop>是<props>的一个元素
2.3.4 捆绑空值
几乎所有情况,都要把值或者java的引用放入一个bean的属性中,但如果要你放入null呢?
对于properties,可以这样
<property name=”someProperty”><null/></properties>
有时需要用null来覆盖自动捆绑,什么是自动捆绑?下面将会讲述。