【问题标题】:Spring 'request' scope thowring exception while using from ExecutorService从 ExecutorService 使用时 Spring 'request' 范围抛出异常
【发布时间】:2016-05-31 05:45:09
【问题描述】:

我有一个控制器和 3 个服务 bean。我的目标是在请求范围内从 ExecutorService 触发 3 个并发 REST 服务。

当它尝试在请求范围内为每个@autowired 服务 bean 初始化 bean 3 次时,我遇到了异常。

谁能帮我找出根本原因并解决问题。

Exception: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.RestService1: 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.

代码:

@RestController
@RequestMapping(value = "/")
public class TestController {

    @Autowired
    private RestService1 restService1;
    @Autowired
    private RestService2 restService2;
    @Autowired
    private RestService3 restService3;
    @RequestMapping(value = "/testConcurency",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE,produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody testConcurency(@Valid @RequestBody TestRequest req, BindingResult errors) throws Exception {

        ExecutorService executor = null;
        Collection<Callable<TestResponse>> tasks = new ArrayList();
        tasks.add(restService1);
        tasks.add(restService2);
        tasks.add(restService3);
        executor = Executors.newFixedThreadPool(tasks.size());
        List<Future<KycResponse>> list = executor.invokeAll(tasks,30, TimeUnit.SECONDS);
    }
}


@Service
@Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
public class RestService1 implements IThreadService, Callable<KycResponse>{
    @Override
    public TestResponse call() throws Exception {
        System.out.println("Hello from"+this);
        // REST service will be called from here.
    }
}

Web.xml 我添加了一个监听器

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

谢谢!

【问题讨论】:

  • 请添加完整的堆栈跟踪

标签: spring multithreading executorservice


【解决方案1】:

当您使用 ExecutorService 时,Runnables 将在与 Web 请求不同的线程中执行,因此在该其他线程中无法访问请求范围(因为那里没有正在运行的请求)。一个解决方案是将服务 bean 的范围更改为应用程序范围(当然首先要确保它们已编程为处理该问题,即没有状态等)。

【讨论】:

  • 你好@dunny,明白你的意思。现在更改此设置将导致许多文件编辑。我尝试了两种选择,1)使其成为Scope(“prototype”)。但我仍然为每个服务 bean 获得相同的对象引用。至少如果 Spring 每次都创建新鲜的 bean 会解决我的问题。 2)为每个服务bean创建局部变量,然后从服务bean注入变量中抛出NullPointerException。
猜你喜欢
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2013-09-28
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多