Spring(07)——單例注入多例之lookup-method
7 單例注入多例之lookup-method
Spring
有一種機制,可以動態的實現或重寫bean
容器中指定bean
的指定方法,然後將返回值指定為bean
容器中的另一個bean
。現針對前文提到的單例bean
需注入多例bean
的應用場景來談談如何使用這種機制。先假設我們有一個單例beanA
需注入一個多例BeanB
型別的bean
,那麼我們可以這樣來做。
1、在beanA
對應的類中定義一個方法用來獲取BeanB
,有這麼一個方法就行,可以是空實現,到時候將由Spring
來為我們重寫或實現,然後返回一個BeanB
型別的bean
。為此,可以將我們的BeanA
如下定義:
public class BeanA { /** * 需要使用到BeanB的方法 */ public void doSomething() { BeanB beanB = this.getBeanB(); System.out.println(beanB); //... } /** * 定義一個返回值為BeanB的方法,用來獲取BeanB型別的bean,該方法將由Spring來重寫。 * @return */ public BeanB getBeanB() { return null; } }
2、在ApplicationContext
中定義一個單例beanA
和一個多例beanB
,同時通過lookup-method
beanA
的getBeanB
方法將會被Spring
重寫並返回bean
容器中的beanB
。<bean id="beanB" class="com.app.BeanB" scope="prototype"/> <bean id="beanA" class="com.app.BeanA"> <!-- 表示將由Spring重寫getBeanB()方法,並返回名為beanB的bean --> <lookup-method name="getBeanB" bean="beanB"/> </bean>
經過以上兩步以後每次在排程beanA
getBeanB()
方法時,Spring
都重新從bean
容器中獲取一個beanB
,因為beanB
定義為多例形式,所以每次都會獲取一個全新的BeanB
物件。在給一個bean
指定了lookup-method
後,Spring
將通過CGLIB
動態的生成一個該bean
對應型別的子類,然後在該子類中實現或重寫lookup-method
元素指定的方法,並從bean
容器中獲取lookup-method
元素指定的bean
作為返回值進行返回。當bean
指定的型別是一個抽象類且lookup-method
指定的方法是一個抽象方法時,Spring
就將實現該抽象方法,否則就是重寫。定義了lookup-method
的bean
真正的型別是Spring
動態生成類的型別,但是它可以被當做bean
本身指定的型別使用,因為動態生成的類就是繼承自bean
本身指定的型別的。
由於Spring
是需要動態生成類來重寫或實現指定的方法的,所以我們必須確保由lookup-method
指定的方法是可以被重寫的,這就要求該方法對子類是可訪問的,而且不能是final
型的。具體來講lookup-method
元素指定的方法需要具有如下形式:
<public|protected> [abstract] <return-type> methodName(no-arguments)
如你所見,lookup-method
指定的方法還不能有引數。
(注:本文是基於Spring4.1.0所寫)