[Spring] 注入Bean属性
通常,JavaBean的属性是私有的,同时拥有一组存取器方法,setXXX()和getXXX()形式存在。Spring可以借助属性的set方法来配置属性的值,以实现setter方式的注入。
Kenny是一个很有天赋的乐曲演奏家,由Intrumentalist类定义,如下:
package com.springinaction.springidol;
public class Instrumentalist implements Performer {
public Instrumentalist() {}
public void perform() throws PerformanceException {
System.out.println("Playing " + song + " : ");
instrument.play();
}
private String song;
public void setSong(String song) {
this.song = song;
}
public String getSong() {
return song;
}
public String screamSong() {
return song;
}
private Instrument instrument;
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
}
Instrument接口定义如下:
package com.springinaction.springidol;
public interface Instrument {
void play();
}
1 注入简单值
在spring中可以使用<property>
元素配置bean的属性,如下例子展示了kenny bean的配置:
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="Jingle Bells" />
</bean>
2 引入其他Bean
Kenny是一个天才的演奏家,他可以演奏任何乐器,只要这个乐器实现了Instrument接口,定义一个乐器类Saxophone:
package com.springinaction.springidol;
public class Saxophone implements Instrument {
public Saxophone() {}
public void play() {
System.out.println("TOOT TOOT TOOT");
}
}
在Kenny演奏萨克斯之前,我们现在spring中将它声明为一个bean,如下所示:
<bean id="saxophone" class="com.springinaction.springidol.Saxophone" />
声明之后就可以把它赋给Kenny演奏了,我们对Kenny的配置做如下修改:
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="Jingle Bells" />
<property name="instrument" ref="saxophone" />
</bean>
下面我们可以执行如下代码让Kenny表演:
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-idol.xml");
Performer performer = (Performer)ctx.getBean("kenny");
performer.perform();
输出结果为:
Playing Jingle Bells :
TOOT TOOT TOOT
注入内部bean
内部bean是定义在其他bean内部的bean,如下配置将萨克斯声明为内部bean:
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="Jingle Bells" />
<property name="instrument">
<bean class="com.springinaction.springidol.Saxophone" />
</property>
</bean>
内部bean并不仅限于setter注入,我们还可以把内部bean装配到构造方法的入参中,正如下面的duke的新声明所展示的:
<bean id="duke" class="com.springinaction.springidol.PoeticJuggler">
<constructor-arg value="25" />
<constructor-arg>
<bean class="com.springinaction.springidol.Sonnet29" />
</constructor-arg>
</bean>
内部bean没有ID属性,虽然为内部bean配置一个ID属性完全是合法的,但是却没有必要。内部类最大的缺点:不能被复用。内部bean仅适用于一次注入,而且也不能被其他bean应用。使用内部bean会影响Spring XML配置的可读性。
3 使用spring的命名空间p装配属性
spring的命名空间p提供了另一种bean属性的装配方式,该方式不需要配置如此多的尖括号。
命名空间p的schema URI为http://www.springframework.org/schema/p
。如果你想使用命名空间p,主需要在spring的XML配置中增加如下一段声明:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
使用范例如下:
<bean id="kenny2" class="com.springinaction.springidol.Instrumentalist"
p:song="Jingle Bells"
p:instrument-ref="saxophone" />
-ref
后缀作为一个标识来告知spring应该装配一个引用而不是字面值。
4 装配集合
当配置集合类型的bean属性时,spring提供了4种类型的集合配置元素。
集合元素 | 用途 |
---|---|
<list> |
装配list类型的值,允许重复 |
<set> |
装配set类型的值,不允许重复 |
<map> |
装配map类型的值,名称和值可以是任意类型 |
<props> |
装配properties类型的值,名称和值必须是String类型 |
当属性为任意的java.util.Collection类型时,<list>
和<set>
几乎可以完全互换。 <map>
和<props>
这两个元素分别对应java.util.Map和java.util.Properties。当我们需要由键-值对组成的集合时,这两种配置元素非常有用。
Hank能够同时演奏多种乐器,由类OneManBand定义:
package com.springinaction.springidol;
import java.util.Collection;
public class OneManBand implements Performer {
public OneManBand() {}
public void perform() throws PerformanceException {
for (Instrument instrument : instruments) {
instrument.play();
}
}
private Collection<Instrument> instruments;
public void setInstruments(Collection<Instrument> instruments) {
this.instruments = instruments;
}
}
我们使用list配置元素为Hank赋予表演时所用到的乐器集合:
<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元素包含一个或多个值,这里的ref元素用来定义在spring上下文中的其他bean引用。当然还可以使用其他的spring设置元素作为list的成员,包括<vaue>
、<bean>
和<null>
。实际上,list可以包含另一个list作为其成员,形成多维列表。
Note:无论<list>
还是<set>
,都可以用来装配类型为java.util.Collection的任意实现或者数组的属性。
装配Map集合
当OneManBand表演时,假设我们还想知道每一个音符是由哪种乐器产生的,OneManBand可以调整如下:
package com.springinaction.springidol;
import java.util.Collection;
import java.util.Map;
public class OneManBand implements Performer {
public OneManBand() {}
public void perform() throws PerformanceException {
for (String key : instruments.keySet()) {
System.out.println(key + ":");
Instrument instrument = instruments.get(key);
instrument.play();
}
}
private Map<String, Instrument> instruments;
public void setInstruments(Map<String, Instrument> instruments) {
this.instruments = instruments;
}
}
使用map元素配置instruments属性,如下所示:
<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中的entry元素由一个键和一个值组成,键和值可以是简单类型,也可以是其他类型的引用,这些属性将帮助我们指定entry的键和值:
属性 | 用途 |
---|---|
key | 指定map中entry的键为String |
key-ref | 指定map中entry的键为spring上下文中其他bean的引用 |
value | 指定map中entry的值为String |
value-ref | 指定map中entry的值为spring上下文中其他bean的引用 |
装配Properties集合
一个范例如下:
<bean id="hank" class="com.springinaction.springidol.XXX">
<property name="instruments">
<props>
<prop key="GUITAR">STRUM STRUM STRUM</prop>
<prop key="CYMBAL">CRASH CRASH CRASH</prop>
<prop key="HARMONICA">HUM HUM HUM</prop>
</props>
</property>
</bean>
Note:术语比较
-
<property>
元素用于把值或bean引用注入到bean的属性中 -
<props>
元素用于定义一个java.util.Properties类型的集合值 -
<prop>
元素用于定义<props>
集合的一个成员。
5 装配空值
通常情况下bean属性的最初值都是null,直到你为它赋值,但是有些bean会为它的属性默认设置一个非空值。如果因为某些特殊原因,必须把属性设置为空值,则可以显式地为该属性装配一个null值。
为属性设置null值,只需使用<null/>
元素,例如:
<property name="someNonNullProperty"><null/></property>
显式地为属性装配null值的另一个理由是覆盖自动装配的值。
转载:http://blog.csdn.net/foreverling/article/details/50878992