首先我們來了解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秒,爲當前系統時間。