【发布时间】: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