diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc index 83276621eba..8f4c06f25b5 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-async.adoc @@ -92,7 +92,7 @@ Kotlin:: ====== The return value can then be obtained by running the given task through the -xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration-spring-mvc[configured] `TaskExecutor`. +xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration-spring-mvc[configured] `AsyncTaskExecutor`. @@ -128,7 +128,7 @@ Here is a very concise overview of Servlet asynchronous request processing: * The controller returns a `Callable`. * Spring MVC calls `request.startAsync()` and submits the `Callable` to - a `TaskExecutor` for processing in a separate thread. + an `AsyncTaskExecutor` for processing in a separate thread. * Meanwhile, the `DispatcherServlet` and all filters exit the Servlet container thread, but the response remains open. * Eventually the `Callable` produces a result, and Spring MVC dispatches the request back @@ -404,11 +404,10 @@ TIP: Spring MVC supports Reactor and RxJava through the For streaming to the response, reactive back pressure is supported, but writes to the response are still blocking and are run on a separate thread through the -xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration-spring-mvc[configured] `TaskExecutor`, to avoid -blocking the upstream source (such as a `Flux` returned from `WebClient`). -By default, `SimpleAsyncTaskExecutor` is used for the blocking writes, but that is not -suitable under load. If you plan to stream with a reactive type, you should use the -xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration-spring-mvc[MVC configuration] to configure a task executor. +xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-configuration-spring-mvc[configured] +`AsyncTaskExecutor`, to avoid blocking the upstream source such as a `Flux` returned +from `WebClient`. + @@ -494,7 +493,7 @@ In `web.xml` configuration, you can add `true [[mvc-ann-async-configuration-spring-mvc]] === Spring MVC -The MVC configuration exposes the following options related to asynchronous request processing: +The MVC configuration exposes the following options for asynchronous request processing: * Java configuration: Use the `configureAsyncSupport` callback on `WebMvcConfigurer`. * XML namespace: Use the `` element under ``. @@ -504,10 +503,9 @@ You can configure the following: * Default timeout value for async requests, which if not set, depends on the underlying Servlet container. * `AsyncTaskExecutor` to use for blocking writes when streaming with -xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-reactive-types[Reactive Types] and for executing `Callable` instances returned from -controller methods. We highly recommended configuring this property if you -stream with reactive types or have controller methods that return `Callable`, since -by default, it is a `SimpleAsyncTaskExecutor`. +xref:web/webmvc/mvc-ann-async.adoc#mvc-ann-async-reactive-types[Reactive Types] and for +executing `Callable` instances returned from controller methods. +The one used by default is not suitable for production under load. * `DeferredResultProcessingInterceptor` implementations and `CallableProcessingInterceptor` implementations. Note that you can also set the default timeout value on a `DeferredResult`, diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/AsyncSupportConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/AsyncSupportConfigurer.java index a43bcb31a54..221d2f8395f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/AsyncSupportConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/AsyncSupportConfigurer.java @@ -22,9 +22,7 @@ import java.util.List; import java.util.concurrent.Callable; import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.lang.Nullable; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.web.context.request.async.CallableProcessingInterceptor; import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor; @@ -49,15 +47,15 @@ public class AsyncSupportConfigurer { /** - * The provided task executor is used to: + * The provided task executor is used for the following: *
    *
  1. Handle {@link Callable} controller method return values. *
  2. Perform blocking writes when streaming to the response * through a reactive (e.g. Reactor, RxJava) controller method return value. *
- *

By default only a {@link SimpleAsyncTaskExecutor} is used. However when - * using the above two use cases, it's recommended to configure an executor - * backed by a thread pool such as {@link ThreadPoolTaskExecutor}. + *

If your application has controllers with such return types, please + * configure an {@link AsyncTaskExecutor} as the one used by default is not + * suitable for production under load. * @param taskExecutor the task executor instance to use by default */ public AsyncSupportConfigurer setTaskExecutor(AsyncTaskExecutor taskExecutor) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java index 733dea43c44..9c1e29f3e0d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java @@ -399,9 +399,9 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter * Set the default {@link AsyncTaskExecutor} to use when a controller method * return a {@link Callable}. Controller methods can override this default on * a per-request basis by returning an {@link WebAsyncTask}. - *

By default a {@link SimpleAsyncTaskExecutor} instance is used. - * It's recommended to change that default in production as the simple executor - * does not re-use threads. + *

If your application has controllers with such return types, please + * configure an {@link AsyncTaskExecutor} as the one used by default is not + * suitable for production under load. */ public void setTaskExecutor(AsyncTaskExecutor taskExecutor) { this.taskExecutor = taskExecutor;