Roh*_*bhu 7 java spring spring-mvc
我遇到了一个问题,当方法返回时,我的过滤器运行了两次CompletionStage.从RequestMapping(此处)的文档中,它是受支持的返回值.
CompletionStage(由CompletableFuture实现),应用程序使用它在自己选择的单独线程中生成返回值,作为返回Callable的替代方法.
由于项目非常复杂,并且有很多并发代码,因此我创建了一个新的简单的spring-boot项目.这是(唯一的)控制器:
@Controller
public class BaseController {
@RequestMapping("/hello")
@ResponseBody
public CompletionStage<String> world() {
return CompletableFuture.supplyAsync(() -> "Hello World");
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个过滤器:
@WebFilter
@Component
public class GenericLoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
System.out.println(httpServletRequest.getMethod() + " " +
httpServletRequest.getRequestURI());
chain.doFilter(request, response);
}
}
Run Code Online (Sandbox Code Playgroud)
当我打电话时curl http://localhost:8080/hello,它会GET /hello在控制台上打印两次.当我更改控制器方法以返回String:
@RequestMapping("/hello")
@ResponseBody
public String world() {
return "Hello World";
}
Run Code Online (Sandbox Code Playgroud)
它只打印一次.即使我将其更改为a Callable,也没有真正的并发意义(当然,spring本身可能会将此作为Async请求处理),因此会出现此行为.
因此,如果spring再次运行整个Web堆栈以获得请求上下文,那么即使这样也没有意义,因为以下内容:
@RequestMapping("/hello")
@ResponseBody
public CompletionStage<String> world() {
return CompletableFuture.supplyAsync(() -> {
System.out.println(RequestContextHolder.currentRequestAttributes());
return "Hello World";
});
}
Run Code Online (Sandbox Code Playgroud)
抛出异常: IllegalStateException: No thread-bound request found...
令人惊讶的是,以下工作:
@RequestMapping("/hello")
@ResponseBody
public Callable<String> world() {
return () -> {
System.out.println(RequestContextHolder.currentRequestAttributes());
return "Hello World";
};
}
Run Code Online (Sandbox Code Playgroud)
所以,我不确定相当多的事情.
Callable和CompletionStage在哪个线程的它是在执行上下文被区别对待.CompletionStage如果无法访问它,则再次运行它是没有意义的.| 归档时间: |
|
| 查看次数: |
1110 次 |
| 最近记录: |