2017-10-07 122 views
0

我們有一個Spring管理的Struts 2應用程序正在運行,其中之前的開發人員在Action類中存儲了HttpServletRequest對象在全局變量中。 做了一些研究之後,我發現默認情況下Struts Action類是線程安全的,因爲它們是爲每個請求實例化的,但在我們的應用程序中,Struts Action類被配置爲Spring bean而沒有提及bean作用域(所以默認情況下它們是單例) 。我認爲這是一個災難的原因,所以我正在尋找一個修復,我發現在官方的Struts以下2以下Spring集成例如:什麼應該是由Spring管理的Struts 2 Action類bean的合適範圍?

<bean id="editService" class="org.apache.struts.edit.service.EditServiceInMemory"/> 

<bean id="editAction" class="org.apache.struts.edit.action.EditAction" scope="prototype"> 

    <property name="editService" ref="editService" /> 

</bean> 

這裏的範圍被設定爲原型,但我的東西它應該是請求,因爲動作類需要爲每個Http請求實例化。請告訴我,我的理解是否正確以及是否是正確的解決方案,而不是將請求對象實例化爲局部變量。

我找到了在堆棧溢出以下問題,但我想在Struts 2中的常用詞彙: Spring Request and Prototype Scope?

+0

[Spring Request and Prototype Scope?](https://stackoverflow.com/questions/6480005/spring-request-and-prototype-scope)可能有重複。我認爲,這幾乎告訴你你想知道什麼。通過請求作用域,您將在httprequest的生命週期中獲得相同的bean實例。所以這取決於你的用例:就像你有你想要共享狀態的行爲一起過濾。 –

+0

嗨羅伯特,這個問題回答了請求和原型bean之間的區別,但我想知道在struts託管的web應用程序中,請求和原型之間應該是什麼樣的正確範圍。 –

+0

@RobertMoskal:我們沒有過濾器,但是我們正在從請求中提取數據並在動作類中進行安全檢查。根據我的理解,實例化的正確方法是在請求範圍內聲明操作類,但在官方文檔中將其作爲原型給出,這是我的困惑。 –

回答

0

這篇文章解釋了相當清楚如何兩項工作:Spring Request and Prototype Scope?

我會說,如果你的應用只使用簡單的動作,你使用的並不重要。如果您使用過濾器或struts攔截器,並且希望在請求管道的不同步驟之間保持狀態,則必須使用請求範圍的bean。否則它再次沒有關係。

我可能會使用基於原型的bean,當基於請求的bean不是絕對必要時。

+0

謝謝羅伯特!實際上,我們有一個父抽象動作類,其中聲明瞭全局請求變量,並由應用程序中的所有動作類擴展和實現。我們只在不同的操作類之間共享狀態(請求對象),這些操作類引用了在父操作類中全局聲明的單個請求對象。所以我的理解是,爲了解決這個問題,動作bean應該在請求範圍內聲明,因爲請求狀態是由一系列操作類共享的。 –

+0

它有一個類層次結構,那麼你實際上只有一個實例化的類,而不是一個鏈,所以我仍然認爲你不需要使用請求作用域bean,但是如果你這樣做,沒有什麼壞處。 –

+1

@RobertMoskal你爲什麼說'沒有傷害,如果你'?當您使用也是數據bean的Struts2控制器的請求範圍時,您從不知道災難,但是控制器本身。 –