1. 程式人生 > >Spring(07)——單例注入多例之lookup-method

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

元素指定beanAgetBeanB方法將會被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-methodbean真正的型別是Spring動態生成類的型別,但是它可以被當做bean本身指定的型別使用,因為動態生成的類就是繼承自bean本身指定的型別的。

由於Spring是需要動態生成類來重寫或實現指定的方法的,所以我們必須確保由lookup-method指定的方法是可以被重寫的,這就要求該方法對子類是可訪問的,而且不能是final型的。具體來講lookup-method元素指定的方法需要具有如下形式:

<public|protected> [abstract] <return-type> methodName(no-arguments)

如你所見,lookup-method指定的方法還不能有引數。

(注:本文是基於Spring4.1.0所寫)