天天看點

Java深度曆險(二) EJB Session Bean有狀态和無狀态的差別與聯系

       剛開始對兩種sessionbean存在誤解,認為有狀态是執行個體一直存在,儲存每次調用後的狀态,并對下一次調用起作用,而認為無狀态是每次調用執行個體化一次,不保留使用者資訊。仔細分析并用實踐檢驗後,會發現,事實恰好相反:有狀态和無狀态會話bean的本質差別是它們的生命期。

       首先解釋一個下面要用到的概念--使用者:sessionbean 的使用者實際上就是直接調用ejb的類的執行個體,甚至是這個執行個體的某個方法。同一個類的不同執行個體對于session bean來說是不同的使用者。

執行個體解析

有狀态的StatefulEjb接口

StatefulEjb的實作

無狀态接口StatelessEjb

無狀态接口StatelessEjb實作

用戶端配置jndi

有狀态的用戶端編寫

結果:

Java深度曆險(二) EJB Session Bean有狀态和無狀态的差別與聯系

無狀态用戶端編寫

結果

Java深度曆險(二) EJB Session Bean有狀态和無狀态的差別與聯系

       有狀态會話bean:每個使用者有自己特有的一個執行個體,在使用者的生存期内,bean保持了使用者的資訊,即“有狀态”;一旦使用者滅亡(調用結束或執行個體結束),bean的生命期也告結束。即每個使用者最初都會得到一個初始的bean。

       無狀态會話bean :bean一旦執行個體化就被加進會話池中,各個使用者都可以共用。即使使用者已經消亡,bean的生命期也不一定結束,它可能依然存在于會話池中,供其他使用者調用。由于沒有特定的使用者,那麼也就不能保持某一使用者的狀态,是以叫無狀态bean。但無狀态會話bean并非沒有狀态,如果它有自己的屬性(變量),那麼這些變量就會受到所有調用它的使用者的影響,這是在實際應用中必須注意的。

   差別的根本原因

      對于有狀态會話Bean來說,隻要有用戶端發送對有狀态會話Bean的通路,伺服器都會建立一個會話Bean執行個體與該用戶端對應,這樣這個執行個體與這個用戶端就是一一對應的。如果用戶端在Bean執行個體中儲存了資訊,之後還可以使用。

       對于無狀态會話Bean來說,伺服器端會維持一個執行個體池,建立好若幹個執行個體對象供用戶端調用。當從用戶端發送建立會話Bean的請求時,并不一定會真的建立 EJB,多數情況下是從執行個體池中得到一個執行個體,用完之後重新放回執行個體池。如果下次再通路,再從執行個體池中取出一個執行個體使用,并不一定是上次的執行個體。即使兩次通路使用的是同一個執行個體,在兩次通路之間也有可能有其他的用戶端通路了該執行個體。是以,并不能保證在多次通路之間的資訊會被儲存。是以,無狀态會話Bean 不會專門儲存用戶端的資訊。

   各自的優缺點

        因為有狀态會話Bean需要儲存特定用戶端的資訊,一個用戶端對應一個執行個體,既是在當時用戶端有連接配接沒有通路的情況下,也要為這個用戶端保留這個執行個體。這樣随着用戶端數量的增加,伺服器端需要建立的執行個體的數量也在增加,增加到一定程度對伺服器的性能就會有一定的影響。為了不對伺服器的性能産生影響,通常伺服器會進行一些優化。當用戶端的數量超過某個值之後,就不建立新的執行個體。雖然不建立新的執行個體,還是需要對使用者響應,這時候就采用共享執行個體的方式。會檢視哪個執行個體雖然處于連接配接狀态,但是沒有通路,然後把這個執行個體的狀态儲存起來,使用這個執行個體為新的請求服務,對于原來的用戶端來說,稱為挂起。如果原來的用戶端又發送請求了,會重新查找一個空閑的執行個體并且把已經儲存好的狀态恢複回來,這個過程稱為激活。是以在有狀态會話Bean的通路過程,經常會發生查找執行個體,激活挂起等操作,是以效率比較低。

       而發送對無狀态會話Bean的請求的時候,可以随便取一個空閑的執行個體為用戶端服務,是以效率比較高。

       有狀态會話Bean的好處是,可以儲存用戶端的狀态,是以用戶端在後續通路的時候就可以少傳遞一些參數。而無狀态會話Bean需要傳遞方法執行過程中需要的所有參數。

   如何選擇

       根據上面分析的有狀态會話Bean和無狀态會話Bean的優缺點。如果要頻繁的通路,并且多次通路之間會共享一些資訊,這時候應該使用有狀态會話Bean。對于不經常使用的功能,可以使用無狀态會話Bean。無狀态會話Bean的使用要比有狀态會話Bean的使用多。

       項目中沒有使用到有狀态的會話bean,對于使用的相同資料,也是通過傳遞參數實作,并非設定到bean中的屬性值中。對于無狀态的會話bean,如果有屬性,則可能影響到所有調用的使用者,因為他是共享的。

   總結

         通過執行個體自己實踐之後的清晰了很多,多動手多動手,TO Do TO DO !