StreamingResponseBodyReturnValueHandler 不使用 applicationTaskExecutor

StreamingResponseBodyReturnValueHandler does not use applicationTaskExecutor

我有 Spring Data REST 个自定义控制器 returns ResponseEntity<StreamingResponseBody>

在我的 application.yaml 文件中,我定义了一个用于 StreamingResponseBody 的自定义任务执行器。

spring:
  task:
    execution:
      pool:
        max-size: 16
        queue-capacity: 100

但是,mvc 仍然使用 SimpleAsyncTaskExecutor,而不是上面定义的

An Executor is required to handle java.util.concurrent.Callable return values.
Please, configure a TaskExecutor in the MVC config under "async support".
The SimpleAsyncTaskExecutor currently in use is not suitable under load.

经过一些调试,我发现 StreamingResponseBodyReturnValueHandler 没有在 WebAsyncTask 类型上设置 applicationTaskExecutor,即 StreamingResponseBodyTask,结果 [=使用 16=]。

Callable<Void> callable = new StreamingResponseBodyTask(outputMessage.getBody(), streamingBody);
WebAsyncUtils.getAsyncManager(webRequest).startCallableProcessing(callable, mavContainer);

当我在 WebMvcAutoConfiguration

中调试此方法时,WebMvcAutoConfiguration 正在获取 applicationTaskExecutor 并正确设置它
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    if (this.beanFactory.containsBean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)) {
        Object taskExecutor = this.beanFactory
            .getBean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME);
        if (taskExecutor instanceof AsyncTaskExecutor) {
            configurer.setTaskExecutor(((AsyncTaskExecutor) taskExecutor));
        }
    }
    Duration timeout = this.mvcProperties.getAsync().getRequestTimeout();
    if (timeout != null) {
        configurer.setDefaultTimeout(timeout.toMillis());
    }
}

我错过了什么吗?如何将 ThreadPoolTaskExecutor 应用于 StreamingResponseBody

spring-data-rest 自定义存储库(@RepositoryRestResource@BasePathAwareController)忽略 AsyncSupportConfigurerRepositoryRestMvcConfiguration#repositoryExporterHandlerAdapter here.
但是 spring-webmvc 适用 AsyncSupportConfigurer 请参见 WebMvcConfigurationSupport#requestMappingHandlerAdapter here

    AsyncSupportConfigurer configurer = getAsyncSupportConfigurer();
    if (configurer.getTaskExecutor() != null) {
        adapter.setTaskExecutor(configurer.getTaskExecutor());
    }
    if (configurer.getTimeout() != null) {
        adapter.setAsyncRequestTimeout(configurer.getTimeout());
    }
    adapter.setCallableInterceptors(configurer.getCallableInterceptors());
    adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors());

如果可能,请使用简单的 @RestController@Controller, 如果没有,您可以创建一个问题 here 来添加对此的支持