當spring容器中作用域不同的bean相互依賴時,可能出現一些問題:當兩個singleton作用域bean存在依賴關係時,或當prototype作用域bean依賴singleton作用域bean時,通過屬性定義依賴關係就足夠了。
但當singleton作用域bean依賴prototype作用域bean時,singleton作用域bean只有一次初始化的機會,它的依賴關係也只在初始化階段被設定,它所依賴的prototype作用域bean則需要每次都得到乙個全新的bean例項,這將導致singleton作用域的bean的依賴得不到即時更新。
例如客戶端程式多次請求singleton時,由於singleton具有單例行為,spring返回給客戶端的將是同乙個singleton bean例項,這不存在任何問題。但如果是客戶端多次請求singleton bean、並呼叫該singleton bean去呼叫prototype bean的方法時,始終都是呼叫同乙個prototype bean例項,這就違背了設定prototype bean 的初衷:本來希望它具有prototype行為,但實際上它卻表現出singleton行為了。
產生的問題:當singleton作用域bean依賴於prototype作用域bean時,會產生不同步的現象。
解決思路:> 部分放棄依賴注入:singleton作用域bean每次需要prototype作用域bean時,主動向容器請求新的bean例項,即可保證每次注入的prototype bean例項都是最新的例項。
> 利用方法注入
第一種方式顯然不是乙個好的做法,**主動請求新的bean例項,必然導致**與spring api 耦合,造成嚴重**汙染。
通常情況下,我們採用第二種做法,使用方法注入。
方法注入通常使用lookup方法注入,利用lookup方法注入可以讓spring容器重寫容器中bean的抽象或具體方法,返回查詢容器中其他bean的結果,被查詢的bean通常是乙個non-singleton bean(儘管也可以是乙個singleton的)。spring通過使用cglib庫修改客戶端的二進位製碼,從而實現上述的要求。
package demo;
public class scopesteelaxe implements axe
@override
public string chop()
}
上面的scopesteelaxe將被部署成prototype作用域bean,並被乙個singleton作用域bean所依賴。如果讓spring容器直接將prototype作用域的bean注入singleton作用域bean,就會出現前面描述的問題。為了解決這個問題,我們在singleton bean 裡新增乙個抽象方法,該方法的返回值型別是被依賴的bean——注意該方法時乙個抽象方法,程式設計師沒有為該方法提供實現,該方法的實現由spring完成。下面為該bean的**:
package demo;
public abstract class scopechinese implements person
//定義乙個抽象方法,該方法將由spring負責實現
public abstract axe getaxe();
@override
public void useaxe()
}
上面的程式中定義了乙個抽象的getaxe()方法,通常情況下,程式不能呼叫這個抽象方法。但spring框架將會負責為該方法提供實現體,這樣這個方法就會變成具體方法了,程式也就可以呼叫該方法了。
為了讓spring知道如何實現該方法,我們需要再配置檔案中使用元素來配置這個方法。
執行結果表明:使用lookup方法注入後,系統每次呼叫getaxe()方法都將生成乙個新的steelaxe例項,這就可以保證當singleton作用域的bean需要全新的bean例項時,直接呼叫getaxe()方法既可,從而可避免一直使用最早注入的bean例項。
ps:要保證lookup方法注入每次產生新的bean例項,必須將目標bean(上例是scopesteelaxe)部署成prototype作用域。否則,如果容器中只有乙個目標bean例項,即使採用lookup方法注入,每次依然返回同乙個bean例項。
lookup方法注入不僅能用於設定注入,也可用於構造注入。
協調作用域不同步的Bean
如果在依賴注入的時候出現這麼乙個情況 乙個singleton bean需要依賴注入乙個prototype bean,如果不採用任何手段,直接注入的話,將會出現這樣乙個結果 每次建立singleton bean例項時,獲取的prototype bean例項也是相同的,從而在使用來看prototype ...
2 5 協調作用域不同步的Bean
在spring容器中,最常見的為singleton與prototype作用域的bean,當我們多次獲取singleton作用域的bean時,得到的都是同乙個例項,而prototype作用域裡則每次都產生乙個新的bean例項。我們知道,spring容器在初始化某個bean前,先會建立被依賴的bean,...
Bean的作用域
bean元素有乙個scope屬性,用於定義bean的作用域,該屬性有如下五個值 1 singleton 單例模式,在整個spring ioc容器中,單例模式作用域的bean都將只生成乙個例項。一般spring容器預設bean的作用域為singleton 2 prototype 與singleton相...