我們通常使用lookup方法注入,它可使Spring替換一個Bean的抽象或具體方法,返回查找容器中,其他Bean的結果,被查找的Bean通常是一個non-singleton Bean。
無狀態的Bean的作用域一般可以配置成singleton單實例,如果我們向singleton的BeanA注入prototype的BeanB,并希望每次調用BeanA的getBeanB()時都能返回一個新的BeanB,使用傳統的注入方式方法將無法實現這樣的要求。因為singleton的Bean注入關聯Bean的動作只有一次,雖然BeanB的作用域是prototype類型,返回的對象不是最開始注入的那個bean。
如果希望每次調用BeanA的getBeanB()時都能返回一個新的BeanB一種可選的方案是讓Bean實現BeanFactoryAware接口,讓BeanA能訪問容器的引用,以下代碼可以實現方式達到目的:
[+] view codepublicclass Bean_A implements BeanFactoryAware{
private Bean_B bean_B=null; private BeanFactory beanFactory=null; @Override publicvoid setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory=beanFactory; } public Bean_B getBean_B(){ returnbeanFactory.getBean("bean_B", Bean_B.class); }}回憶第一篇里講的Bean的生命周期,當一個Bean的POJO類實現了BeanFactoryAware接口時,當Bean實例化完成并調用setter方法降屬性也設置完畢后,會調用BeanFactoryAware接口的setBeanFactory方法,這樣我們便可以得到BeanFactory的一個引用。使用BeanFactory我們便可以獲取一個全新的scope="prototype"的Bean實例了。
但是,這種方法,使得一個純凈的POJO類被污染了,因此一般情況下不適用這種方法。
1. 使用lookup方法注入Spring IoC容器有復寫Bean方法的能力,這項功能歸功于CGLib類包,CGLib可以在運行期動態的操作Class字節碼,使Spring替換一個Bean的抽象或具體方法,現在我們將上面的功能使用lookup方法注入來實現:
[+] view codepublicclass Bean_A{
private Bean_B bean_B=null; public Bean_B getBean_B() { returnbean_B; } publicvoid setBean_B(Bean_B bean_B) { this.bean_B = bean_B; }}注意,我們這里的Bean_A是一個純潔的POJO類。然后在Spring配置文件中為Bean_A添加lookup方法注入,使Spring替換getBean_B() 方法即可。
[+] view code<beanid="bean_B"class="smzq.Bean_B"scope="prototype"/>
<beanid="bean_A"class="smzq.Bean_A"> <lookup-methodname="getBean_B"bean="bean_B"/></bean>測試:

大功告成。![]()
注:lookup方法還可以為bean動態的創建子類或實現類,現在我們聲明一個接口,如下:
[+] view codepublicinterface BeanInterface {
Bean_B getBean_B(); }同樣在Spring的配置文件中配置,但這次配置的不是類,而是一個接口。很神奇吧!
[+] view code<beanid="bean_B"class="smzq.Bean_B" scope="prototype"/>
<beanid="beanInter"class="smzq.BeanInterface"> <lookup-methodname="getBean_B"bean="bean_B"/></bean>再測試一下:

由此可見,Spring確實為我們的BaseInter接口創建了實現類。那么這里是抽象類呢?Spring也會為其創建一個子類。
<lookup-method>元素只有兩個屬性:
name:指定要讓Spring實現的或者替換的方法名稱,該方法返回一個Bean對象。
bean:指定name屬性指定的方法的返回值。
新聞熱點
疑難解答