亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

作用域“會話”對當前線程無效;IllegalStateException:找不到線程綁定的請求

作用域“會話”對當前線程無效;IllegalStateException:找不到線程綁定的請求

MM們 2019-11-11 14:02:35
我有一個控制器,希望每個會話都唯一。根據spring文檔,實現有兩個細節:1.初始Web配置為了在請求,會話和全局會話級別(網絡范圍的Bean)支持Bean的作用域,在定義Bean之前,需要一些較小的初始配置。web.xml如文檔所示,我已經添加了以下內容:<listener>  <listener-class>    org.springframework.web.context.request.RequestContextListener  </listener-class></listener>2.范圍豆作為依賴項如果要將(例如)HTTP請求范圍的bean注入另一個bean,則必須注入AOP代理來代替范圍的bean。我通過@Scope提供proxyMode如下所示對bean進行了注釋:@Controller@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)public class ReportBuilder implements Serializable {    ...    ...}問題盡管進行了上述配置,我還是收到以下異常:org.springframework.beans.factory.BeanCreationException:創建名稱為“ scopedTarget.reportBuilder”的bean時出錯:當前線程的作用域“會話”未激活;如果您打算從單例中引用它,請考慮為此bean定義作用域代理。嵌套異常為java.lang.IllegalStateException:未找到線程綁定的請求:您是在實際Web請求之外引用請求屬性,還是在原始接收線程之外處理請求?如果您實際上是在Web請求中操作并且仍然收到此消息,則您的代碼可能在DispatcherServlet / DispatcherPortlet之外運行:在這種情況下,請使用RequestContextListener或RequestContextFilter公開當前請求。更新1以下是我的組件掃描。我有以下內容web.xml:<context-param>  <param-name>contextClass</param-name>  <param-value>    org.springframework.web.context.support.AnnotationConfigWebApplicationContext  </param-value></context-param><context-param>  <param-name>contextConfigLocation</param-name>  <param-value>org.example.AppConfig</param-value></context-param><listener>  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>以及以下內容AppConfig.java:@Configuration@EnableAsync@EnableCaching@ComponentScan("org.example")@ImportResource("classpath:applicationContext.xml")public class AppConfig implements AsyncConfigurer {  ...  ...}更新2我創建了一個可重現的測試用例。這是一個較小的項目,因此存在差異,但是會發生相同的錯誤。有相當多的文件,所以我上傳它作為一個tar.gz以megafileupload。
查看完整描述

3 回答

?
qq_遁去的一_1

TA貢獻1725條經驗 獲得超8個贊

問題不在于您的Spring注釋,而在于您的設計模式。您將不同的作用域和線程混合在一起:

  • 單身人士

  • 會話(或請求)

  • 作業線程池

單身人士可以在任何地方使用,沒關系。但是,會話/請求范圍在附加到請求的線程之外不可用。

即使請求或會話不再存在,異步作業也可以運行,因此無法使用依賴于請求/會話的bean。同樣也沒有辦法知道,如果您正在另一個線程中運行作業,哪個線程是發起者請求(這意味著aop:proxy在這種情況下沒有幫助)。


我覺得你的代碼看起來像要作合同 ReportController,報表制作,UselessTask和ReportPage之間。有沒有辦法只使用一個簡單的類(POJO)來存儲UselessTask中的數據并在ReportController或ReportPage中讀取它,而不再使用ReportBuilder?


查看完整回答
反對 回復 2019-11-11
?
largeQ

TA貢獻2039條經驗 獲得超8個贊

如果還有其他人堅持同一觀點,以下解決了我的問題。


在web.xml中


 <listener>

            <listener-class>

                    org.springframework.web.context.request.RequestContextListener 

            </listener-class>

  </listener>

會話中組件


@Component

@Scope(value = "session",  proxyMode = ScopedProxyMode.TARGET_CLASS)

在pom.xml中


    <dependency>

        <groupId>cglib</groupId>

        <artifactId>cglib</artifactId>

        <version>3.1</version>

    </dependency>


查看完整回答
反對 回復 2019-11-11
?
哈士奇WWW

TA貢獻1799條經驗 獲得超6個贊


原因


原因是使用多個線程。如Spring Guide中所述,請求對象在這些線程中不可用:


DispatcherServlet,RequestContextListener并且RequestContextFilter都做同樣的事情,即綁定HTTP請求對象添加到服務該請求的線程。這使得在請求鏈和會話范圍內的bean可以在調用鏈的更下游使用。


解決方案1


可以使請求對象可用于其他線程,但是它對系統有一些限制,這在所有項目中可能都不可行。我從在多線程Web應用程序中訪問請求范圍的Bean獲得了此解決方案:


我設法解決了這個問題。我開始使用SimpleAsyncTaskExecutor而不是WorkManagerTaskExecutor/ ThreadPoolExecutorFactoryBean。好處是SimpleAsyncTaskExecutor永遠不會重復使用線程。那只是解決方案的一半。解決方案的另一半是使用RequestContextFilter而不是RequestContextListener。RequestContextFilter(以及DispatcherServlet)具有一個threadContextInheritable屬性,該屬性基本上允許子線程繼承父上下文。


解決方案2


唯一的其他選擇是在請求線程內使用會話范圍的Bean。就我而言,這是不可能的,因為:


控制器方法用注釋@Async;

控制器方法將啟動批處理作業,該批處理作業將線程用于并行作業步驟。


查看完整回答
反對 回復 2019-11-11
  • 3 回答
  • 0 關注
  • 908 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號