天天看點

Spring Bean Scope 有狀态的Bean 無狀态的Bean

 在Spring的Bean配置中,存在這樣兩種情況:

<bean id="testManager" class="com.sw.TestManagerImpl" scope="singleton" />  

 <bean id="testManager" class="com.sw.TestManagerImpl" scope="prototype" />  

當然,scope的值不止這兩種,還包括了request,session 等。但用的最多的還是singleton單态,prototype多态。

singleton表示該bean全局隻有一個執行個體,Spring中bean的scope預設也是singleton.

prototype表示該bean在每次被注入的時候,都要重新建立一個執行個體,這種情況适用于有狀态的Bean.

對于SSH架構的系統,很少關心這方面,因為我們用到的一般都是singleton. Bean的注入由Spring管理。

對于有狀态的Bean呢?

下面是一個有狀态的Bean

package com.sw;  

public class TestManagerImpl implements TestManager{  

    private User user;    

    public void deleteUser(User e) throws Exception {  

        user = e ;           //1  

        prepareData(e);  

    }  

    public void prepareData(User e) throws Exception {  

        user = getUserByID(e.getId());            //2  

        .....  

        //使用user.getId();                       //3  

    }     

}  

如果該Bean配置為singleton,會出現什麼樣的狀況呢?

如果有2個使用者通路,都調用到了該Bean.

假定為user1,user2

當user1 調用到程式中的1步驟的時候,該Bean的私有變量user被付值為user1

當user1的程式走到2步驟的時候,該Bean的私有變量user被重新付值為user1_create

理想的狀況,當user1走到3步驟的時候,私有變量user應該為user1_create;

但如果在user1調用到3步驟之前,user2開始運作到了1步驟了,由于單态的資源共享,則私有變量user被修改為user2

這種情況下,user1的步驟3用到的user.getId()實際用到是user2的對象。

而如果是prototype的話,就不會出現資源共享的問題。

對于SSH來說,Bean的配置是沒錯的,配置為singleton ;實際應該是這個例子不應該用私有變量。這樣就使得這個Bean

由無狀态變成了有狀态Bean.還是應該盡量使用無狀态Bean.如果在程式中出現私有變量,盡量替換為參數。

對于每個通路私有變量的方法增加變量傳入或者通過ThreadLocal來擷取也是不錯的方法。

真正出現上面代碼問題的也是少數,出現的時候,一般是為了圖友善,一個很多方法都要用到的變量,如果都需要用參數的

方式傳遞多麻煩呀,這樣私有變量多好,不用參數那樣醜陋。但是醜陋并不代表不好,以對的,自己習慣的方式程式設計,才能

盡量避免問題的發生。

本文轉自快樂就好部落格園部落格,原文連結:http://www.cnblogs.com/happyday56/p/5566945.html,如需轉載請自行聯系原作者