首先我们来了解Spring Bean的两个作用域,Singleton和Prototype。
Singleton类型的Bean在容器只被创建一次,以后的每次调用都只调用这个实例。
Prototype类型的Bean则在每次被请求调用的时候就会创造一个新的Bean。
这样,当一个Singleton类型的Bean A中包含一个prototype类型的Bean B时,由于Singleton类型的Bean A只初始化一次,所以就无法保证在每次调用这个Singleton类型的Bean A时它所包含的prototype类型的Bean B都是最新的。
这时我们就需要另一种注入方法,LookUp注入。
LookUp注入利用的是IoC容器能够复写Bean中的抽象方法的能力,从而返回指定名字的Bean的实例,至于原理可以参考Spring 2.0的Reference。
Public abstract Bean getBean();
注意:使用lookUp方法注入需要cglib-nodep-2.1_3.jar文件
下面看一个简单的返回系统时间的例子:
Prototype类型的Bean
qiudawei115.lookUp.PrototypeBean.java
package qiudawei115.lookUp;
//这是个PrototypeBean
import java.util.Calendar;
public class PrototypeBean {
Calendar c=Calendar.getInstance();
public void displayTime(){
//返回系统当前时间
System.out.println(c.getTime());
//System.out.println(Calendar.getInstance().getTime());
}
}
Singleton类型的Bean
qiudawei115.lookUp.SingletonBean.java
package qiudawei115.lookUp;
public abstract class SingletonBean {
PrototypeBean pb;
public PrototypeBean getPb() {
return pb;
}
public void setPb(PrototypeBean pb) {
this.pb = pb;
}
//抽象方法用来产生PrototypeBean
public abstract PrototypeBean getPrototypeBean();
}
配置文件applicationContext.xml,红体字为LookUp注入需要的
<?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-2.0.xsd">
<!-- Hello World! -->
<bean id="helloWorld" class="qiudawei115.base.HelloWorld">
<property name="message" value="Hello World!"></property>
</bean>
<!-- Constructor DI -->
<bean id="fb" class="qiudawei115.constructor.FirstBean"></bean>
<bean id="sb" class="qiudawei115.constructor.SecondBean"></bean>
<bean id="cb" class="qiudawei115.constructor.ConstructorBean">
<constructor-arg>
<ref bean="fb"/>
</constructor-arg>
<constructor-arg>
<ref bean="sb"/>
</constructor-arg>
</bean>
<!-- Setter DI -->
<bean id="sfb" class="qiudawei115.setter.FirstBean"></bean>
<bean id="ssb" class="qiudawei115.setter.SecondBean"></bean>
<bean id="setterBean" class="qiudawei115.setter.SetterBean">
<property name="sfb" ref="sfb"></property>
<property name="ssb" ref="ssb"></property>
</bean>
<!-- LookUp DI -->
<bean id="pb" class="qiudawei115.lookUp.PrototypeBean" scope="prototype"></bean>
<bean id="lsb" class="qiudawei115.lookUp.SingletonBean" >
<property name="pb" ref="pb"></property>
<lookup-method name="getPrototypeBean" bean="pb"/>
</bean>
</beans>
测试Bean
qiudawei115.lookUp.LookUpMain.java
package qiudawei115.lookUp;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class LookUpMain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassPathResource resource=new ClassPathResource("applicationContext.xml");
BeanFactory beanFactory=new XmlBeanFactory(resource);
System.out.println("-- First Time --");
SingletonBean sb=(SingletonBean)beanFactory.getBean("lsb");
System.out.print("getPb()方法:");
sb.getPb().displayTime();
System.out.print("getPrototypeBean()方法:");
sb.getPrototypeBean().displayTime();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("-- Second Time --");
sb=(SingletonBean)beanFactory.getBean("lsb");
System.out.print("getPb()方法:");
sb.getPb().displayTime();
System.out.print("getPrototypeBean()方法:");
sb.getPrototypeBean().displayTime();
}
}
得到的时间应该是前三次一样,最后一次延迟2秒,为当前系统时间。