异步请求处理功能必须在 Servlet 容器级别启用。MVC 配置也为异步请求暴露了几个选项。
Servlet Container / Servlet 容器
过滤器和 Servlet 声明有一个 asyncSupported 标志,需要设置为 true 以启用异步请求处理。此外,Filter 映射应该被声明为处理 ASYNC javax.servlet.DispatchType。
在 Java 配置中,当你使用 AbstractAnnotationConfigDispatcherServletInitializer来初始化 Servlet 容器时,这将自动完成(这个暂时不知道咋使用的)。
在 web.xml 配置中,你可以在 DispatcherServlet 和 Filter 声明中添加 <async-supported>true</async-supported>,在 Filter 映射中添加<dispatcher>ASYNC</dispatcher>。
异步需要在 servlet 容器级别启用异步支持,如果内嵌 Tomcat 的话,以编程方式初始化 DispatcherServlet 的话(下面的方式对应的是 web.xml 中设置的逻辑),可以如下方式开启
package cn.mrcode.study;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.ContextLoaderListener;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;import javax.servlet.ServletContext;import javax.servlet.ServletRegistration;/*** @author mrcode*/public class MyWebApplicationInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) {// 加载 Spring web application configurationAnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();context.register(AppConfig.class);// Manage the lifecycle of the root application contextservletContext.addListener(new ContextLoaderListener(context));// 创建和注册 DispatcherServletDispatcherServlet servlet = new DispatcherServlet(context);ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);registration.setLoadOnStartup(1);registration.addMapping("/");// 启用异步支持registration.setAsyncSupported(true);}}
Spring MVC
MVC 配置暴露了以下与异步请求处理有关的选项:
- Java 配置:使用 WebMvcConfigurer 上的 configureAsyncSupport 回调。
- XML 配置:使用
<mvc:annotation-driven>下的<async-support>元素。
你可以配置以下内容:
- 异步请求的 默认超时值,如果没有设置,则取决于底层 Servlet 容器。
- AsyncTaskExecutor:用于在使用反应式类型流时进行阻塞式写入,以及执行从控制器方法返回的可调用实例。如果你使用反应式类型的流媒体或有返回 Callable 的控制器方法,我们强烈建议配置这个属性,因为默认情况下,它是一个 SimpleAsyncTaskExecutor。
- DeferredResultProcessingInterceptor 实现和 CallableProcessingInterceptor 实现。
注意,你也可以在 DeferredResult、ResponseBodyEmitter 和 SseEmitter 上设置默认超时值。对于一个 Callable,你可以使用 WebAsyncTask 来提供一个超时值。
