1. 程式人生 > >spring bean scope 的幾種型別

spring bean scope 的幾種型別

宣告:

這是轉載的,內容源自網路整理而成。

----------------------------------------------------------------------------------------

正文】

Spring容器最初提供了兩種bean的scope型別:singleton和prototype,但釋出2.0以後,又引入了另外三種scope型別:request、session和global session,這三種只能在web 應用中才可以使用。

一、基礎概念

singleton: 在Spring的IoC容器中只存在一個物件例項,所有該物件的引用都共享這個例項。Spring 容器只會建立該bean定義的唯一例項,這個例項會被儲存到快取中,並且對該bean的所有後續請求和引用都將返回該快取中的物件例項,一般情況下,無狀態的bean使用該scope。

prototype:每次對該bean的請求都會建立一個新的例項,一般情況下,有狀態的bean使用該scope。
request:每次http請求將會有各自的bean例項,類似於prototype。
session:在一個http session中,一個bean定義對應一個bean例項。
global session:在一個全域性的http session中,一個bean定義對應一個bean例項。典型情況下,僅在使用portlet context的時候有效。

其次說明spring的預設scope(bean作用域)是singleton

二、自定義scope型別

在spring2.0中作用域是可以任意擴充套件的,你可以自定義作用域,甚至你也可以重新定義已有的作用域(但是你不能覆蓋singleton和 prototype),spring的作用域由介面org.springframework.beans.factory.config.Scope來定 義,自定義自己的作用域只要實現該介面即可,下面給個例項:
我們建立一個執行緒的scope,該scope在表示一個執行緒中有效,程式碼如下:

publicclass MyScope implements Scope { 
      privatefinal ThreadLocal threadScope = new ThreadLocal() {
          protected Object initialValue() {
             returnnew HashMap(); 
           } 
     }; 
     public Object get(String name, ObjectFactory objectFactory) { 
         Map scope = (Map) threadScope.get(); 
         Object object = scope.get(name); 
        if(object==null) { 
           object = objectFactory.getObject(); 
           scope.put(name, object); 
         } 
        return object; 
      } 
     public Object remove(String name) { 
         Map scope = (Map) threadScope.get(); 
        return scope.remove(name); 
      }
      publicvoid registerDestructionCallback(String name, Runnable callback) { 
      }
    public String getConversationId() {
       // TODO Auto-generated method stub
        returnnull;
     } 
}
【總結】

①問:scope型別什麼時候宣告為singleton,何時宣告為prototype?

預設scope是singleton。

無狀態的bean使用該scope。

有狀態的bean使用prototype。

有狀態和無狀態會話bean的本質區別是它們的生命期。

bean保持了使用者的資訊,即“有狀態”

無狀態會話bean :bean一旦例項化就被加進會話池中,各個使用者都可以共用。由於沒有特定的使用者,那麼也就不能保持某一使用者的狀態,所以叫無狀態bean。但無狀態會話bean 並非沒有狀態,如果它有自己的屬性(變數),那麼這些變數就會受到所有呼叫它的使用者的影響,這是在實際應用中必須注意的。

在ssh2 專案中 , struts2的action交由spring管理的時候 ,spring預設是singleton的 ,而struts2的action顯然是有狀態的 ,所以必須顯示設定為 scope=“prototype”;
但是對那些Dao的實現類推介scope=“singleton” ,因為這些類沒有狀態,用singleton只需維護一個例項,顯然效能高一些。

③比較:

用singleton 的效能要高一些 ,因為只有一個例項;

④實際應用舉例:

之前在開發過程中遇到了一個問題,當request發起下一個請求的時候,action中的屬性值並沒有清除,而是繼續採用上次使用過的引數值進行查詢並響應,導致資料查詢不真實或失敗。對此,有同事告訴我說,需要在spring配置檔案的bean中新增屬性scope=prototype。結果還真的有用。