2012-04-13 98 views
7

我不知道如何應用在CDI不同的bean作用域(@ApplicationScoped@SessionScoped@RequestScoped)的作品。我瞭解生命週期,但容器中的哪些地方存儲了這些信息?我在JSF bean上使用這些註釋。不同的bean作用域在服務器上如何工作?

如何是這些bean存儲在服務器上,以及如何能夠知道哪些豆屬於誰的服務器。

例如,一個bean有一個@SessionScoped存儲在HTTPSession對象的幕後? @ApplicationScoped是否存儲在地圖實例變量中的豆ServletContext?如果是這樣,那麼線程安全性如何?我想我誤解了它,但如果有人能教會我會發生什麼,它們被存儲在何處(不同的範圍),服務器如何知道哪些bean屬於誰......就像其他ID一樣(不僅會話ID)?

我btw使用Java EE 6所有參考實現。

回答

3

例如,一個bean有一個存儲在HTTPSession對象後面的@SessionScoped?具有@ApplicationScoped的bean是否存儲在ServletContext中的映射實例變量中?

對於Web層,這的確是發生了什麼。如果這個bean已經被實例化了,你可以通過手動遍歷所有映射中的所有對象來找到它。

@RequestScoped雖然是一種特殊的東西。在網絡層中,這與請求屬性映射相對應,但是該範圍也適用於對例如遠程會話bean或處理消息的消息驅動的bean。在這種情況下,沒有http請求,因此沒有請求屬性映射。很可能這些存儲在「其他地方」,可能是在由代理設置和取消設置的TLS(線程本地存儲)中。

如果是這樣,怎麼樣線程安全。

應用程序和會話範圍的bean本身並不是線程安全的。 必須照顧線程安全性,例如通過使用線程安全的數據結構,synchronized關鍵字或本質上線程安全的bean類型(如@Stateful註釋bean)。

+0

好,所以沒有更多的「騙人把戲」,以它比:)不過,據我所知,'@ ApplicationScoped' AKA的ServletContext是不是線程安全的,因爲多個客戶端可以嘗試在同一時間去改變它......但爲什麼'@ SessionScoped'線程不安全?是不是隻有一個客戶可以訪問同一個bean? – LuckyLuke 2012-04-13 17:21:31

+0

對於'SessionScoped',實際上沒有限制多少個請求可以同時訪問它。當然,他們通常都來自同一個客戶。考慮來自同一個窗口的多個窗口,多個標籤或多個AJAX請求。 – 2012-04-13 17:39:01

+0

好的,那麼你提到了,如果一個bean本質上是線程安全的,比如EJB(至少有一些類型)......那麼你的意思是它保留爲JSF中使用的bean的屬性? – LuckyLuke 2012-04-13 18:47:46