【问题标题】:Spring Autowired and parallelStreamsSpring Autowired 和 parallelStreams
【发布时间】:2021-01-21 11:35:55
【问题描述】:

如何让 @Autowired 注释在 Spring REST 请求上下文中由 .parallelStream() 创建的线程中工作?

这是我想要完成的一个简化示例:

@RestController
public class Controller {
    @Autowired
    private Service service;

    @GetMapping(value = "getStrings")
    public List<String> getAllStrings(List<String> request) {
        return request.parallelStream()
                .map(requestItem -> service.getString(requestItem))
                .collect(Collectors.toList());
    }

}
@Service
public class Service {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private HttpHeaders httpHeaders;

    public String getString(String request) {
        // some code that uses resttemplate and httpheaders here, returns string
        // assume this request takes 2 sec to complete hence the need to make multiple calls in parallel
    }
}

实际运行此代码时收到的错误是

org.springframework.beans.factory.BeanCreationException:创建名为“scopedTarget.httpHeaders”的bean时出错:范围“请求”对于当前线程不活动;如果您打算从单例中引用它,请考虑为该 bean 定义一个作用域代理;嵌套异常是 java.lang.IllegalStateException:未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。

解决此问题的一种方法是将 httpHeaders 作为参数传递给 getString() ,但这需要对使用该方法的每个其他类进行大量重构

我发现 parallelStreams 可以使用自定义线程池,但不知道如何获取 spring 请求上下文使用的当前线程池(或者如果重用同一个线程池甚至可以解决我的问题)

【问题讨论】:

    标签: java spring multithreading


    【解决方案1】:

    你可以试试添加

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

    为您服务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-11
      • 2012-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多