spring mvc和threads以及java.lang.IllegalStateException:找不到线程绑定请求

时间:2013-11-12 16:27:36

标签: java multithreading spring-mvc

我们使用带有flexfish作为客户端的glassfish / websphere的spring mvc。 其中一个web服务需要向客户端返回指示,然后继续异步执行而不需要返回任何内容。

我们尝试使用纯Java线程,但它没有用,因为spring无法访问Web应用程序上下文。

然后我们尝试在#34;弹簧方式中使用线程" (使用@async +) 但春天异常:

  

12-11-2013 16:11:44,769 [SimpleAsyncTaskExecutor-1]错误   com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService.handleCRMEventsSending(线路:   254)[userrrr | 30605808 | 2c90908b424ca07a01424ca374c00000] -   sendQrmEvent请求[问卷id:   2c90908b424ca07a01424ca374c00000]失败,异常:错误   创建名称为“scopedTarget.sessionCachedUserMetadata'”的bean:   范围'会议'当前线程不活动;考虑   如果您打算引用它,则为该bean定义范围代理   来自单身人士;嵌套异常是java.lang.IllegalStateException:   找不到线程绑定请求:您指的是请求属性吗?   在实际的Web请求之外,或处理外部的请求   原来收到的帖子?如果你实际在里面经营   一个Web请求仍然收到此消息,您的代码可能是   在DispatcherServlet / DispatcherPortlet之外运行:在这种情况下,   使用RequestContextListener或RequestContextFilter来公开   当前的要求。 (10065)   com.app.questionnaire.exceptions.CRMEventException:sendCrmEvent   [问卷号:2c90908b424ca07a01424ca374c00000]的请求失败   异常:创建名称为bean的错误   ' scopedTarget.sessionCachedUserMetadata':范围'会话'不是   当前线程有效;考虑为。定义范围代理   如果你打算从单身中引用它,这个bean;嵌套   异常是java.lang.IllegalStateException:没有线程绑定请求   发现:您是指实际的请求属性吗?   Web请求,或处理原始请求之外的请求   接收线程?如果您实际在Web请求中操作   并且仍然收到此消息,您的代码可能正在外面运行   DispatcherServlet / DispatcherPortlet:在这种情况下,请使用   RequestContextListener或RequestContextFilter公开当前   请求。在   com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService.handleCRMEventsLogics(CloseQuestionnaireBusinessActionsService.java:780)     在   com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService.handleCRMEventsSending(CloseQuestionnaireBusinessActionsService.java:251)     在   com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService $$ FastClassByCGLIB $$ 729836cc.invoke()     在net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)at   org.springframework.aop.framework.Cglib2AopProxy $ CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)     在   org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)     在   org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)     在   org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)     在   org.springframework.aop.framework.Cglib2AopProxy $ DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)     在   com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService $$ EnhancerByCGLIB $$ 149b3c4c.handleCRMEventsSending()     在   com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessService.postCloseQuestionnaire(CloseQuestionnaireBusinessService.java:111)     在   com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessService $$ FastClassByCGLIB $$ 2c8c6561.invoke()     在net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)at   org.springframework.aop.framework.Cglib2AopProxy $ DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:617)     在   com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessService $$ EnhancerByCGLIB $$ 1be443b3.postCloseQuestionnaire()     在   com.app.questionnaire.logic.QuestionnaireBusinessService.postCloseQuestionnaire(QuestionnaireBusinessService.java:327)     在   com.app.questionnaire.logic.QuestionnaireBusinessService $$ FastClassByCGLIB $$ 3ba23fb7.invoke()     在net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)at   org.springframework.aop.framework.Cglib2AopProxy $ CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)     在   org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)     在   org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)     在   org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)     在   org.springframework.aop.framework.Cglib2AopProxy $ DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)     在   com.app.questionnaire.logic.QuestionnaireBusinessService $$ EnhancerByCGLIB $$ 95911765.postCloseQuestionnaire()     在   com.app.questionnaire.util.PostClosePreformerProcess.doClose(PostClosePreformerProcess.java:28)     在   com.app.questionnaire.util.PostClosePreformerProcess $$ FastClassByCGLIB $$ 3553cc1c.invoke()     在net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)at   org.springframework.aop.framework.Cglib2AopProxy $ CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)     在   org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)     在   org.springframework.aop.interceptor.AsyncExecutionInterceptor $ 1.call(AsyncExecutionInterceptor.java:80)     at java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:303)     在java.util.concurrent.FutureTask.run(FutureTask.java:138)at   java.lang.Thread.run(Thread.java:662)

的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
    version="2.5">

    <display-name>advisor-server</display-name>

    <!-- ========= Context parameters ========= -->

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:ApplicationContext.xml</param-value>
    </context-param>

    <context-param>
        <description>Parameter specifying the location of the log4j
            configuration file</description>
        <param-name>log4jConfigLocation</param-name>
        <param-value>file:${advisorLog4jConfigLocation}</param-value>
    </context-param>

    <!-- ========= Listeners ========= -->

    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener
        </listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>

    <listener>
        <display-name>serviceRefRegistrar</display-name>
        <listener-class>com.app.application.ServiceRefRegistrar
        </listener-class>
    </listener>

    <!-- Loads configuration to make sure we don't crash during runtime in case 
        of parsing errors -->
    <listener>
        <listener-class>com.app.application.ApplicationConfigListener
        </listener-class>
    </listener>

    <!-- ========= filters ========= -->

    <filter>
            <filter-name>requestContextFilter</filter-name>
            <filter-class>org.springframework.web.filter.RequestContextFilter
            </filter-class>
    </filter>
    <filter-mapping>
            <filter-name>requestContextFilter</filter-name>
            <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>LoggingFilter</filter-name>
        <filter-class>com.app.general.logging.LoggingFilter
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>LoggingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>AdviserRequestFilter</filter-name>
        <filter-class>com.app.commons.application.AdviserRequestFilter
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>AdviserRequestFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>



</web-app>

spring.xml

<beans >

    <!-- Context -->
    <context:component-scan base-package="com.modelity.advisor" />
    <tx:annotation-driven transaction-manager="transactionManager" />


    <!-- Activates @Scheduled and @Async annotations for scheduling -->  
    <task:annotation-driven />


</beans>


@Component
public class PostClosePreformerProcess{

    @Autowired
    private QuestionnaireBusinessService questionnaireService;

    public PostClosePreformerProcess() {

    }


    @Async
    public void doClose(String questionnaireId) {
        try {
            questionnaireService.postCloseQuestionnaire(questionnaireId);
        } catch (Exception e) {
            AdvisorLogger.error(this, "Post Closed Failed", e.getMessage(), e);
        }
    }


    public QuestionnaireBusinessService getQuestionnaireService() {
        return questionnaireService;
    }


    public void setQuestionnaireService(
            QuestionnaireBusinessService questionnaireService) {
        this.questionnaireService = questionnaireService;
    }
}




@Service
public class CloseQuestionnaireBusinessService {

    @Autowired
    private PostClosePreformerProcess postClosePreformerProcess;

    public PreCloseQuestionnaireDto preCloseQuestionnaire(String questionnaireId) {

                postClosePreformerProcess.doClose(questionnaireId);
}
}

编辑: 实际上我们需要保持会话/请求范围,因为异步(线程)部分需要在会话范围内定义的应用程序内使用bean 例如一个bean(异常抱怨的那个):

@Component("sessionCachedUserMetadata")
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Lazy(true)
public class UserMetadataSessionCachedService implements UserMetadataBusinessService {

0 个答案:

没有答案