java - Spring 启动 : "Scope ' request' is not active for the current thread"in Asynch method

标签 java spring spring-mvc spring-boot

我在 Spring Boot Controller 中有下一个简单的请求方法:

@Autowired
    private BillServ billServ;
...

@RequestMapping("/chrgcheck")
public String chrgCheck() {
  Future<Result> fut = null;
  fut = billServ.useCheck();

 while (!fut.isDone()) {
       try {
    Thread.sleep(100);
  } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  } 
   }
 try {
    if (fut.get().err ==0) {
      return "OK";
    } else {
      return "ERROR";
    }
  } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    return "ERROR";
  } catch (ExecutionException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    return "ERROR";
}

}

调用服务bean的异步方法billServ.useCheck();

  @Service
  @Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS)
  public class BillServ {
  ...
    @Async
    public Future<Result> useCheck() {
        Result res = new Result();

        System.out.println("Try-1");

        check.checkMe(1);

        res.err=0;
        return new AsyncResult<Result>(res);
    }

它调用了请求作用域 bean check.checkMe() 的另一种方法,因为我需要为每个请求处理单个 bean:

@Component
  @Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS)
  public class Check {

    public void checkMe(int i) {
      System.out.println("checkMe:"+i);

    }
  }

因此,当我调用请求“/chrgcheck”时,出现下一个错误:

  java.util.concurrent.ExecutionException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.check': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at com.ric.web.BillingController.chrgCheck(BillingController.java:99)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

为什么会这样?我应该在我的项目中纠正什么?

最佳答案

Springs Request Scope 实现是线程绑定(bind)的。因此,如果您启动一个新线程(这就是 @Async 所做的),则该线程未绑定(bind)到请求,因此 spring 请求范围实现失败。

关于java - Spring 启动 : "Scope ' request' is not active for the current thread"in Asynch method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39324982/

相关文章:

java - cucumber 中的场景大纲 Hook 之后

java - 从 Java 中的字符串函数返回字符串生成器?

java - Spring Boot Rest Controller 使用 Jackson 和 Hibernate 将 POJO 转换为 JSON 时出错

java - 如何将 mongodb 的连接对象提供给 JasperFillManager.fillReport() - Spring MongoDB Jasper Integration

spring - 在 MongoDB for Spring 中查找/删除 @DBref 列表项

java - Spring MVC 应用程序的默认资源文件夹

java - 使用 log4j 生成日志文件的问题

java - JDBC MySQL 读写 TIMESTAMP 自 Unix Epoch 以来的毫秒数

java - 用户登录和 session 劫持后的 Spring Security cookie

java - Swagger Springfox配置问题