有狀態的bean和無狀態的bean的區別

有狀態對象(Stateful Bean) :就是有實例變量的對象,可以保存數據,是非線程安全的。每個用戶有自己特有的一個實例,在用戶的生存期內,bean保持了用戶的信息,即“有狀態”;一旦用戶滅亡(調用結束或實例結束),bean的生命期也告結束。即每個用戶最初都會得到一個初始的bean。

無狀態對象(Stateless Bean):就是沒有實例變量的對象,不能保存數據,是不變類,是線程安全的。bean一旦實例化就被加進會話池中,各個用戶都可以共用。即使用戶已經消亡,bean 的生命期也不一定結束,它可能依然存在於會話池中,供其他用戶調用。由於沒有特定的用戶,那麼也就不能保持某一用戶的狀態,所以叫無狀態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、Prototype和有無狀態的bean是兩個概念。。

Singleton作用域表示該bean全局只有一個實例,Spring中bean的scope默認也是singleton,這種情況適用於無狀態的Bean。

如Service層、Dao層用默認singleton就行,雖然Service類也有dao這樣的屬性,但dao這些類都是沒有狀態信息的,也就是相當於不變(immutable)類,所以不影響。Struts2中的Action因爲會有User、BizEntity這樣的實例對象,是有狀態信息的,在多線程環境下是不安全的,所以Struts2默認的實現是Prototype模式。在Spring中,Struts2的Action中,scope要配成prototype作用域。

Springmvc默認是singleton單例模式,Struts2默認的實現是Prototype模式。

Spring使用ThreadLocal解決線程安全問題。我們知道在一般情況下,只有無狀態的Bean纔可以在多線程環境下共享,在Spring中,絕大部分Bean都可以聲明爲singleton作用域。就是因爲Spring對一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非線程安全狀態採用ThreadLocal進行處理,讓它們也成爲線程安全的狀態,因爲有狀態的Bean就可以在多線程中共享了。

參考

有狀態和無狀態的對象區別
Spring Bean Scope 有狀態的Bean 無狀態的Bean

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章