我在尝试访问rxjava Schedulers.io()的线程中的Spring会话范围bean时遇到异常
Caused by: 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.
这是我的scoped bean
@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
@Getter
@Setter
public class SearchSession {
List<String> results;
}
我的控制器
@Controller
@AllArgsConstructor(onConstructor=@__(@Autowired))
@Slf4j
public class SearchController {
private SearchService searchService;
private SearchSession searchSession;
@GetMapping("/search")
public DeferredResult<ModelAndView> getResults() {
DeferredResult<ModelAndView> deferredResult = new DeferredResult<>();
searchService.search("param1", "param2")
.map(results -> {
searchSession.setResults(results);
return results;
)
.subscribeOn(Schedulers.io())
.subscribe(
results -> {
ModelAndView view = new ModelAndView("search");
view.addObject("results", results);
deferredResult.setResult(view);
);
return deferredResult;
}
}
我尝试定义一个扩展RequestContextListener的类,并在调用RequestContextHolder.setRequestAttributes时将参数inheritable设置为true,以允许最初处理请求的线程与RxJava线程之间的继承,但它不起作用。
public class InheritableRequestContextListener extends RequestContextListener {
private static final String REQUEST_ATTRIBUTES_ATTRIBUTE =
InheritableRequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES";
@Override
public void requestInitialized(ServletRequestEvent requestEvent) {
if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) {
throw new IllegalArgumentException(
"Request is not an HttpServletRequest: " + requestEvent.getServletRequest());
}
HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest();
ServletRequestAttributes attributes = new ServletRequestAttributes(request);
request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
LocaleContextHolder.setLocale(request.getLocale());
RequestContextHolder.setRequestAttributes(attributes, true);
}
}
我还尝试创建一个由Spring管理的自定义RxJava调度程序,但它不起作用。
@Bean
public Scheduler scheduler() {
final ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("SearchThread-%d")
.setDaemon(true)
.build();
return Schedulers.from(Executors.newFixedThreadPool(10, threadFactory));
}
您是否知道如何在RxJava线程中访问我的Spring会话范围bean?