56

狀態會話bean定義如下:何時使用無狀態會話Bean來使用有狀態會話Bean?

狀態會話Bean對象的狀態由它的值的實例變量的 的。在有狀態會話Bean中,實例 變量表示唯一客戶端Bean會話的狀態。因爲 客戶端與其bean交互(「會談」),這個狀態通常被稱爲會話狀態 。

無狀態會話bean定義如下:

無狀態會話Bean無狀態會話Bean不維護與客戶端的 會話狀態。當客戶端調用無狀態bean的 方法時,bean的實例變量可能包含特定於該客戶端的狀態 ,但僅在 調用的持續時間內。該方法完成後,不應保留客戶端特定狀態 。但是,客戶端可能會更改共用無狀態bean中的實例變量 的狀態,並且此狀態將保留爲 ,直到下一次調用共用無狀態bean。除方法調用期間的 以外,無狀態bean的所有實例均爲 等效,允許EJB容器將實例分配給任何 客戶端。也就是說,無狀態會話bean的狀態應該適用於所有客戶端的 。

它也提到無狀態會話bean的優點如下:

因爲無狀態會話bean可以支持多個客戶端,他們可以爲需要大量客戶端的 應用 提供更好的可擴展性。通常,應用程序需要比有狀態會話Bean更少的無狀態會話 bean來支持相同數量的 客戶端。

所以我想到的問題是什麼時候應該使用有狀態會話bean?爲了我對這個問題的天真理解,我們應該堅持儘可能地使用無狀態會話bean。

應該使用有狀態會話bean的應用程序是什麼?任何好的例子?

Session Bean

+0

相關:http://stackoverflow.com/questions/8887140/jsf-request-scoped-bean-keeps-recreating-new-stateful-session-beans-on-every-req – BalusC

回答

95

首先,你必須瞭解如何把咖啡豆創建並在服務器上進行處理。

對於無狀態會話bean服務器可以在池中維護可變數量的實例。每次客戶請求這樣一個無狀態bean時(例​​如通過一種方法),選擇一個隨機實例來提供該請求。這意味着如果客戶端執行兩個後續請求,那麼有可能兩個不同的無狀態bean實例爲請求提供服務。事實上,兩個請求之間沒有會話狀態。此外,如果客戶端消失,無狀態bean不會被銷燬,並且可以服務來自其他客戶端的下一個請求。

另一方面,有狀態會話bean與客戶端緊密連接。每個實例都被創建並綁定到一個客戶端,並僅提供來自該特定客戶端的請求。所以如果你對一個有狀態bean執行了兩個後續請求,那麼你的請求將始終來自該bean的同一個實例。這意味着您可以在請求之間保持對話狀態。客戶端在生命週期結束時調用一個remove方法,這個bean被銷燬/準備好進行垃圾回收。

當使用無狀態還是有狀態的?

這主要取決於你是否想保持會話狀態。例如,如果您有一個方法可以合計數字並返回結果,那麼您使用無狀態bean是因爲它只有一次操作。如果您再次使用其他號碼調用此方法,則您不再對以前的添加結果感興趣。

但如果你想例如計算客戶端已經完成的請求數,你必須使用一個狀態bean。在這種情況下,重要的是知道如何往往是客戶端請求過這個bean的方法,所以你必須在bean(例如,用一個變量)來維護會話狀態。如果你在這裏使用無狀態bean,那麼客戶端的請求將會每次從不同的bean中獲得,從而導致你的結果混亂。

+13

「*如果客戶端消失bean也被摧毀*「。事實上,有狀態會話bean沒有得到自動銷燬,除非'@ Remove'('javax.ejb')飾的方法是顯式調用(該方法甚至不需要編碼。它可以簡單地空/空因爲它是用@ @ Remove'註解)。如果關聯客戶忘記銷燬有狀態會話bean,這個bean將被保留在服務器上晃來晃去,直到容器本身決定利用自己的策略將其刪除。我錯了嗎? – Tiny

+3

當然你是對的。在bean的生命週期的更多信息可以在這裏找到:http://docs.oracle.com/javaee/6/tutorial/doc/giplj.html – tobiasdenzler

27

我覺得用一個有狀態會話bean最大的例子是一個購物車,您存儲哪個用戶希望購買的所有產品。