spring-boot - StreamingResponseBodyReturnValueHand

我有Spring Data REST返回 ResponseEntity<StreamingResponseBody> 的自定义 Controller

在我的 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不设置 applicationTaskExecutorWebAsyncTask 上输入即StreamingResponseBodyTask结果是 SimpleAsyncTaskExecutor被使用。

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

WebMvcAutoConfiguration正在拿起 applicationTaskExecutor并正确设置它,当我在 WebMvcAutoConfiguration 中调试此方法时

@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)忽略 AsyncSupportConfigurer 参见 RepositoryRestMvcConfiguration#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添加对此的支持

关于spring-boot - StreamingResponseBodyReturnValueHandler 不使用 applicationTaskExecutor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67029252/

相关文章:

reactjs - React Portal 中 nextJS 应用程序的转发样式

python - 类型错误 : forward() takes 2 positional argum

android - 如何在 Android 中更改 TextInputLayout 的 boxStr

c# - 使用 Newtonsoft.JSON 自定义转换器读取具有不同输入的 json

javascript - SwiftUI:在 macOS 上与 WKWebView 的 Javasc

modbus - Minimalmodbus:在同一个串口上读取多个从机

python - VSCode 终端不显示所有行

git - 如何使用 gitlab-ci.yml 进行简单的 pull ?

uml - 将关联类添加到组合关系

javascript - 如何让 Bootstrap Toasts 不自动消失?