一个简单的例子讲述注入
Kenny是个演奏家,由Instrumentalist类定义,代码如下:
package com.springinaction.springidol;
public class Instrumentalist implements Performer {
public Instrumentalist() {}
public void perform() throws PerformanceException {
System.out.print("Playing " + song + " : ");
instrument.play();
}
private String song;
public void setSong(String song) {
this.song = song;
}
private Instrument instrument;
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
}
Instrumentalist有两个属性:song和Instrument。song属性包含了要演奏的歌曲。Instrument属性包含到Instrument的引用。
Instrument定义了下面的接口:
package com.springinaction.springidol;
public interface Instrument {
public void play();
}
因为Instrumentalist类有默认的构造函数,所以Kenny可以在Spring被声明为一个<bean>,如下XML:
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist" />
尽管Kenny已经定义为Instrumentalist,但是没有song和Instrument,他还是没法演奏。下面介绍如何通过setter方法注入。
为了演奏,使用setter注入给Kenny一个歌曲,如XML:
<bean id="kenny"
class="com.springinaction.springidol.Instrumentalist" >
<property name="song" value="Jingle Bells" />
</bean>
这样,一旦Instrumentalist被实例化,Spring用setter方法就把<property>元素中的歌曲注入到song对象中。这样做的和通过java来设置歌曲的最根本区别是:在Spring中设置,Instrumentalist bean是代码松耦合的。也就是说,Instrumentalist没有硬编码到特定歌曲,并且执行更加灵活。
以上是注入一个数值,下面看看怎么注入其他的bean。
Kenny还会使用其他乐器,只要这个乐器集成Instrument接口。如果Kenny最喜欢萨克斯,我们就给其定义一个萨克斯的类。Saxophone
package com.springinaction.springidol;
public class Saxophone implements Instrument {
public Saxophone() {}
public void play() {
System.out.println("TOOT TOOT TOOT");
}
}
在Kenny演奏萨克斯之前,必须在Spring中声明一个萨克斯的<bean>.如下XML:
<bean id="saxophone"
class="com.springinaction.springidol.saxophone"
</bean>
有了saxophone之后,可以让Kenny演奏了,此时修改kenny bean,使用setter注入来设置Instrument属性:
<bean id="kenny"
class="com.springinaction.springidol.Instrumentalist" >
<property name="song" value="Jingle Bells" />
<property name="Instrument" ref="saxophone" />
</bean>
测试:
写一个main方法:
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/springinaction/springidol/spring-idol.xml");
Performer performer = (Performer) ctx.getBean("kenny");
performer.perform();
}
打印结果:
Playing Jingle Bells : TOOT TOOT TOOT
当然也可以注入内部bean
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist" >
<property name="song" value="Jingle Bells" />
<property name="Instrument" >
<bean class = "class="com.springinaction.springidol.saxophone" ">
</property>
</bean>
但是内部bean最大的缺点就是不能被复用。内部bean只用于注入,不能被其他bean引用。