1.2注入Bean属性
通常javaBean的属性都是私有的,通过get,set方法的形式存在,Spring可以借助属性的set方法来配置属性的值。下面我们以一位参赛者为例,他是一位有音乐天赋的演奏家:
public class InstrumentList implements Performer{
public InstrumentList(){}
private String song;
private int age;
private Instrument instrument;
public InstrumentList(int age,String song,Instrument instrument){
this.age=age;
this.song=song;
this.instrument=instrument;
}
@Override
public void perform() throws PerformanceExcetion {
System.out.print(age+"'s player is Playing :"+song );
instrument.play();
}
public String getSong() {
return song;
}
public void setSong(String song) {
this.song = song;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String screamSong(){
return song;
}
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
}
从上述代码中我们可看到Instrumentalist有三个属性:age,song和instrument,song是要演奏的歌曲名称,instrument是所使用的乐器。
下面定义了Insrument接口:
public interface Instrument {
public void play();
}
下面我们应该在Spring的XML文件中声明InstrumentaList这边Bean:
<bean id="instrumenter1" class="com.Impl.InstrumentList"> </bean>
这里我们虽然声明了这个Bean,但是没有为它注入任何的属性值,因此他没有办法演奏,接下来我们看一下如何注入。
1.2.1注入简单值
在Spring中我们可以使用<property>元素来装配Bean的属性:
<bean id="instrumenter1" class="com.Impl.InstrumentList">
<property name="song" value="爱如潮水"></property>
<property name="age" value="22"></property>
</bean>
一旦InstrumentaList被实例化,Spring就会调用<property>元素所指定的属性的setter方法为该属性注入值,这里value属性可以指定任意类型
注意:value为其注入数字型的值和String没有任何区别,会自动转换。
1.2.2 引用其他Bean
instrumenter2可以演奏任何乐器,只要这个乐器实现了Instrument接口,就可以用任何乐器,演奏任何歌曲。比如我们这里有两个乐器,钢琴和小提琴搜实现了乐器这个接口:
public class piano implements Instrument{
public piano(){}
public String song="as long as ";
public String getSong() {
return song;
}
public void setSong(String song) {
this.song = song;
}
@Override
public void play() {
System.out.println("piano piano piano");
}
}
public class violino implements Instrument{
public violino(){}
@Override
public void play() {
System.out.println("violino violino violino");
}
}
在我们要演奏这个乐器的是我们首先应该先注入乐器:
<bean id="violino" class="com.violino"></bean>
<bean id="piano" class="com.piano"></bean>
声明了这两个乐器之后,我们就可以演奏了 :
<bean id="instrumenter2" class="com.Impl.InstrumentList">
<property name="song" value="爱如潮水"></property>
<property name="instrument" ref="piano"></property>
</bean>
接下来我们做个测试观察输出结果是否如我们想的:
ApplicationContext cxt=new ClassPathXmlApplicationContext(
"classpath:/spring/spring.xml");
Performer performer=(Performer) cxt.getBean("instrumenter2");
performer.perform();
System.exit(0);
输出:0's player is Playing :爱如潮水piano piano piano
这里我们可以看到,我们没有给演奏者注入年龄,自动赋值0.
注入内部Bean
我们已经看到同一个演奏者可以演奏任何一种乐器,同样任何一种乐器可以被任何人所使用,那么这样很不卫生。也就是这里的Bean被共享了。这里我们想实现每个演奏者有属于自己的乐器,我们可以是内部Bean,这样某一个乐器就归属于某一个人使用:
<bean id="onself" class="com.Impl.InstrumentList">
<property name="song" value="爱如潮水"></property>
<property name="instrument" >
<bean class="com.piano"></bean>
</property>
</bean>
内部Bean是通过直接声明一个bean元素作为<property>元素的子节点而定义的,内部Bean不仅限于setter注入,还可以把内部Bean装配到构造方法的参数中:
<bean id="onself2" class="com.Impl.InstrumentList">
<constructor-arg value="12"/>
<constructor-arg value="爱如潮水"/>
<constructor-arg>
<bean class="com.piano"></bean>
</constructor-arg>
</bean>
注意:内部Bean没有ID属性,虽然我们可以为内部Bean配置一个ID属性是完全合法的,但时并没有太大的必要,因为我们永远不会通过名字去引用内部Bean。这样突出 了内部Bean的最大缺点:他们不能被复用。内部Bean仅适用于一次注入,而且不能被其他的Bean所引用。
1.2.3 使用Spring的命名空间p装配属性
命名空间p的shcema的URi为:http://www.springframework.org/schema/p,如果想使用p标签需要在xml配置生增加如下说明:
xmlns:p="http://www.springframework.org/schema/p"
通过此声明我们可以使用p:作为Bean元素所有属性的前缀来装配Bean的属性,例如:
<bean id="testp1" class="com.Impl.InstrumentList"
p:song="我好想你"
p:age="22"
p:instrument-ref="violino" />
这里我们通过使用p:song设置了song的属性值,p:instrument-ref设置了一个ID为violino的Bean引用来装配instument属性。-ref后缀作为一个标示来告知Spring应该装配的是一个引用而不是字面值。
使用<property>还是命名空间p是一样的。
1.2.4 装配集合
在配置集合类型的Bean属性的时候,Spring提供了4中类型的集合匹配元素:
集合元素 | 用途 |
<list> | 允许重复 |
<set> | 不允许重复 |
<map> | 键值任意 |
<props> | 键值必须都为string |
为了装饰Spring中如何装配集合,我们让某一个人作为一个乐队,这个人可以同时演奏多种乐器:
public class OnemanBand implements Performer{
public OnemanBand(){}
private Collection<Instrument> instruments;
public void setInstruments(Collection<Instrument> instruments){
this.instruments=instruments;
}
@Override
public void perform() throws PerformanceExcetion {
for(Instrument instrument:instruments){
instrument.play();
}
}
}
首先我们使用List去装配元素:
<bean id="OnemanBane" class="com.entity.OnemanBand">
<property name="instruments">
<list>
<ref bean="piano"/>
<ref bean="violino"/>
</list>
</property>
</bean>
<list>元素可以包含一个或者多个,-ref元素用来定义spring上下文中的其他Bean引用,同样我们可以使用set去装配,将List换成set就可以
装配Map
public class OnemanBandWithInstrumen implements Performer{
public OnemanBandWithInstrumen(){}
private Map<String,Instrument> instruments;
public void setInstruments(Map<String,Instrument> instruments){
this.instruments=instruments;
}
@Override
public void perform() throws PerformanceExcetion {
for(String key:instruments.keySet()){
System.out.println("使用"+key+";");
Instrument instrument=instruments.get(key);
instrument.play();
}
}
}
使用map装配:
<!-- <bean id="OnemanBandWithInstrumen" class="com.entity.OnemanBandWithInstrumen"> -->
<!-- <property name="instruments"> -->
<!-- <map> -->
<!-- <entry key="钢琴" value-ref="piano"></entry> -->
<!-- <entry key="小提琴" value-ref="violino"></entry> -->
<!-- </map> -->
<!-- </property> -->
<!-- </bean> -->
public class OnemanBandWithInstrumen implements Performer{
public OnemanBandWithInstrumen(){}
private Properties instruments;
public void setInstruments(Properties instruments){
this.instruments=instruments;
}
@Override
public void perform() throws PerformanceExcetion {
Enumeration<Object> enu =instruments.elements();
while(enu.hasMoreElements()){
Object value=enu.nextElement();
System.out.println(value);
}
}
}
<bean id="OnemanBandWithInstrumen" class="com.entity.OnemanBandWithInstrumen">
<property name="instruments">
<props>
<prop key="钢琴">pian! pinao !</prop>
<prop key="小提琴">violino! violino !</prop>
</props>
</property>
</bean>
<property>元素用于把值或Bean引用注入到Bean的属性中
<props>元素用于定义一个java.util.Properties类型的集合值
<prop>元素用于定义<props>集合中的一个成员