3 回答
TA貢獻(xiàn)1725條經(jīng)驗(yàn) 獲得超8個(gè)贊
問(wèn)題不在于您的Spring注釋,而在于您的設(shè)計(jì)模式。您將不同的作用域和線程混合在一起:
單身人士
會(huì)話(或請(qǐng)求)
作業(yè)線程池
單身人士可以在任何地方使用,沒(méi)關(guān)系。但是,會(huì)話/請(qǐng)求范圍在附加到請(qǐng)求的線程之外不可用。
即使請(qǐng)求或會(huì)話不再存在,異步作業(yè)也可以運(yùn)行,因此無(wú)法使用依賴于請(qǐng)求/會(huì)話的bean。同樣也沒(méi)有辦法知道,如果您正在另一個(gè)線程中運(yùn)行作業(yè),哪個(gè)線程是發(fā)起者請(qǐng)求(這意味著aop:proxy在這種情況下沒(méi)有幫助)。
我覺(jué)得你的代碼看起來(lái)像要作合同 ReportController,報(bào)表制作,UselessTask和ReportPage之間。有沒(méi)有辦法只使用一個(gè)簡(jiǎn)單的類(POJO)來(lái)存儲(chǔ)UselessTask中的數(shù)據(jù)并在ReportController或ReportPage中讀取它,而不再使用ReportBuilder?
TA貢獻(xiàn)2039條經(jīng)驗(yàn) 獲得超8個(gè)贊
如果還有其他人堅(jiān)持同一觀點(diǎn),以下解決了我的問(wèn)題。
在web.xml中
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
會(huì)話中組件
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
在pom.xml中
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超6個(gè)贊
原因
原因是使用多個(gè)線程。如Spring Guide中所述,請(qǐng)求對(duì)象在這些線程中不可用:
DispatcherServlet,RequestContextListener并且RequestContextFilter都做同樣的事情,即綁定HTTP請(qǐng)求對(duì)象添加到服務(wù)該請(qǐng)求的線程。這使得在請(qǐng)求鏈和會(huì)話范圍內(nèi)的bean可以在調(diào)用鏈的更下游使用。
解決方案1
可以使請(qǐng)求對(duì)象可用于其他線程,但是它對(duì)系統(tǒng)有一些限制,這在所有項(xiàng)目中可能都不可行。我從在多線程Web應(yīng)用程序中訪問(wèn)請(qǐng)求范圍的Bean獲得了此解決方案:
我設(shè)法解決了這個(gè)問(wèn)題。我開(kāi)始使用SimpleAsyncTaskExecutor而不是WorkManagerTaskExecutor/ ThreadPoolExecutorFactoryBean。好處是SimpleAsyncTaskExecutor永遠(yuǎn)不會(huì)重復(fù)使用線程。那只是解決方案的一半。解決方案的另一半是使用RequestContextFilter而不是RequestContextListener。RequestContextFilter(以及DispatcherServlet)具有一個(gè)threadContextInheritable屬性,該屬性基本上允許子線程繼承父上下文。
解決方案2
唯一的其他選擇是在請(qǐng)求線程內(nèi)使用會(huì)話范圍的Bean。就我而言,這是不可能的,因?yàn)椋?/p>
控制器方法用注釋@Async;
控制器方法將啟動(dòng)批處理作業(yè),該批處理作業(yè)將線程用于并行作業(yè)步驟。
- 3 回答
- 0 關(guān)注
- 958 瀏覽
添加回答
舉報(bào)
