装配Bean
一、声明Bean
创建一个接口:
package cn.edu.stu.springidol; public interface Performer { void perform(); }
实现类:
public class Juggler implements Performer { private int beanBags = 3; public Juggler() { } public Juggler(int beanBags) { this.beanBags = beanBags; } @Override public void perform() { System.out.println("JUGGLING " + beanBags + " BEANBAGS"); } }
Spring XML配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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="duke" class="cn.edu.stu.springidol.Juggler"> <constructor-arg value="15" /> </bean> </beans>
<constructor-arg>配置通过构造器注入参数beanBags=15,如果不配置,默认beanBags=3
运行结果:
通过构造器注入对象引用:
public interface Poem { void recite(); } public class Sonnet29 implements Poem { private static String[] LINES = { "When, in disgrace with fortune and men's eyes,", "I all alone beweep my outcast state." }; public Sonnet29() { } @Override public void recite() { for(String s : LINES) System.out.println(s); } }
public class PoeticJuggler extends Juggler { private Poem poem; public PoeticJuggler(Poem poem) { super(); this.poem = poem; } public PoeticJuggler(int beanBags, Poem poem) { super(beanBags); this.poem = poem; } public void perform() { super.perform(); System.out.println("While reciting..."); poem.recite(); } }
PoeticJuggler类的构造器需要传入一个Poem对象引用
现在XML配置文件中将Sonnet29声明为一个bean
<bean id="sonnet29" class="cn.edu.stu.springidol.Sonnet29" />
然后声明一个新的Bean,通过构造器注入对象引用:
<bean id="poeticDuke" class="cn.edu.stu.springidol.PoeticJuggler">
<constructor-arg value="15" />
<constructor-arg ref="sonnet29" />
</bean>
运行结果:
通过工厂方法创建Bean:
有时候静态工厂方法是实例化对象的唯一方法,如单例类
public class Stage { private Stage() { } private static class StageSingletonHolder { static Stage instance = new Stage(); } public static Stage getInstance() { return StageSingletonHolder.instance; } }
XML配置方法:
<bean id="theStage" class="cn.edu.stu.springidol.Stage" factory-method="getInstance" />
<factory-method>属性允许调用一个指定的静态方法,从而代替构造方法创建一个类的实例
Bean的作用域:
Spring Bean默认的作用域是singleton,在一个Bean定义只有一个对象实例,如果需要Bean可以被实例化任意次(每次调用创建一个实例),需要使用prototype作用域
<bean id="ticket" class="cn.edu.stu.springidol.Ticket" scope="prototype" />
这样每次调用Bean,返回不同实例
Ticket t1 = (Ticket) ctx.getBean("ticket"); Ticket t2 = (Ticket) ctx.getBean("ticket"); System.out.println(t1 == t2);
结果为false,如果把作用域改成singleton,结果变为true。
Bean的作用域还有request、session、global-session。
初始化和销毁Bean:
当实例化一个Bean时,可能需要执行一些初始化操作确保该Bean处于可用状态,同样,不再需要Bean,将其从容器中移除时,可能还需要按顺序执行一些清除工作。
public class Auditorium { public void turnOnLights() { System.out.println("Turn on lights"); } public void turnOffLights() { System.out.println("Turn off lights"); } }
当auditorium bean初始化时,需要调用turnOnLights方法,移除时,需要调用turnOffLights方法。
<bean id="auditorium" class="cn.edu.stu.springidol.Auditorium" init-method="turnOnLights" destroy-method="turnOffLights" />
init-method指定初始化方法,destroy-method指定移除方法
二、注入Bean属性
public interface Instrument { void play(); } public class Saxphone implements Instrument { @Override public void play() { System.out.println("TOOT TOOT TOOT"); } } public class Instrumentalist implements Performer { public Instrumentalist() { } @Override public void perform() { System.out.print("Playing " + song + " : "); instrument.play(); } private String song; public void setSong(String song) { this.song = song; } public String getSong() { return song; } private Instrument instrument; public void setInstrument(Instrument i) { instrument = i; } }
XML配置:
<bean id="saxphone" class="cn.edu.stu.springidol.Saxphone" /> <bean id="kenny" class="cn.edu.stu.springidol.Instrumentalist"> <property name="song" value="Jingle Bells" /> <property name="instrument" ref="saxphone" /> </bean>
注入内部Bean,kenny还可以这样配置:
<bean id="kenny" class="cn.edu.stu.springidol.Instrumentalist"> <property name="song" value="Jingle Bells" /> <property name="instrument"><bean class="cn.edu.stu.springidol.Saxphone" /></property> </bean>
内部Bean不能被复用,仅适用于一次注入,而且不能被其他Bean引用。
装配集合:
public class OneManBand implements Performer { private Collection<Instrument> instruments; public void setInstruments(Collection<Instrument> instruments) { this.instruments = instruments; } @Override public void perform() { for(Instrument i : instruments) i.play(); } }
<bean id="hank" class="cn.edu.stu.springidol.OneManBand">
<property name="instruments">
<list>
<ref bean="saxphone" />
<ref bean="..." />
<ref bean="..." />
</list>
</property>
</bean>
saxphone必须已经被声明为一个Bean。