2009-04-23 223 views
6

我有一個Web應用程序中使用Spring和Hibernate與Struts(它運行在Tomcat)線程春季

調用順序是這樣的......

Struts動作調用春季服務豆這又調用Spring DAO bean。 DAO實現是一個Hibernate實現。

問題是 我所有的spring beans都運行在同一個線程中嗎? 我可以存儲在ThreadLocal的東西,並把它在另一個豆?

我敢肯定這不會在Stateless Session Bean的工作。 EJB容器可以(或將)爲每個會話bean的調用產生一個新線程

彈簧容器的功能是否一樣?即在同一個線程中運行所有的bean?在測試用例我通過Thread.currentThread()得到了相同的ID的getId()和兩個beans-這使我相信,在行動

只有一個線程 -

當我試圖JUnit測試。

或者是不可預知的行爲? 還是會在Tomcat服務器上運行時更改?

澄清 我不希望在兩個線程之間交換數據。我想將數據放入ThreadLocal中,並能夠從調用堆棧中的所有bean中檢索它。只有當所有的bean都在同一個線程中時,這纔會起作用。

+0

你能發佈一些示例代碼嗎?我不確定你想要達到什麼目的。 – 2009-04-23 17:58:32

回答

15

Spring不生成線程。 Tomcat的確如此。春天只是爲你創造和佈置物體。

來自瀏覽器的每個請求在一個請求被處理。處理請求的是Tomcat。它是創建線程來處理請求的Tomcat。

假設您剛剛在Spring中創建了一個名爲「X」的單例bean。然後,所有請求都使用同一個X實例。

春天豆不住在一個線程。他們只是分配在堆上。

+0

因此,當在Tomcat下運行時,我的端到端流將處於一個線程之下嗎? – 2009-04-23 16:33:02

+0

是的,假設一切都在同一個應用程序服務器實例上。 – 2009-04-23 18:22:23

+0

這是迄今爲止最好的解釋。 – 2009-04-23 18:35:46

1

我所有的春豆都會在同一個線程中運行 嗎?我可以將 東西在ThreadLocal中,並得到 它在另一個豆? AFAIK你提到的組件(服務bean,DAO bean - 我猜它們是普通的spring bean),Spring不會產生新的線程。我不明白你的用例(即在兩個線程之間交換數據)。

對於大多數web應用中,產生新線程爲每個新的請求,如果你想分享兩個請求之間的數據,你通常: - 使用GET/POST參數來傳遞數據 - 使用會話分享數據

爲了回答你的問題,我非常確定spring容器不會爲大多數組件生成線程。

0

是的,你可以這樣做。同一個線程將被用來執行你的動作,所以ThreadLocal將起作用。通常,同樣的線程也用於無狀態會話Bean,假設它運行在同一個應用服務器實例中。儘管如此,我不會依賴這個,因爲它可能是供應商的依賴。

我們使用這種技術,以便隨時隨地訪問呼叫者身份代碼。我們也使用會話bean和jms,但明確地在容器之間傳遞信息並在每個入口點設置ThreadLocal。這樣,無論bean(session或mdb)是否是本地的都沒關係。

0

除了所有其他的答案,我只是補充如下:

通常要切換線程的唯一原因是因爲parallellity一些要求。由於這通常不會在複雜性方面免費,所以通常會在發生這種情況時得到明確通知。內似乎是一個請求的單線程處理

切換線程實際上是極其複雜的。這通常只發生在容器中的一個地方,並且通常由接收來自外部客戶端的請求的tcp/ip套接字讀取器處理。這些讀線程通常決定哪個線程(池)應該處理請求並將請求轉發給該線程。之後,請求保留在該線程中。

所以通常會/可能發生的唯一的事情就是額外的線程獲得並行性或異步處理(如JMS)創建的。