任务执行与调度

如果上下文中没有 Executor bean,Spring Boot 会自动配置一个 AsyncTaskExecutor。 当启用虚拟线程(使用 Java 21+ 且 spring.threads.virtual.enabled 设置为 true)时,这将是一个使用虚拟线程的 SimpleAsyncTaskExecutor。 否则,它将是一个带有合理默认值的 ThreadPoolTaskExecutor。 无论哪种情况,自动配置的执行器都会自动用于:

  • 异步任务执行(@EnableAsync

  • Spring for GraphQL 控制器方法返回 Callable 时的异步处理

  • Spring MVC 的异步请求处理

  • Spring WebFlux 的阻塞执行支持

如果您在上下文中定义了自定义的 Executor,常规任务执行(即 @EnableAsync)和 Spring for GraphQL 都会使用它。 但 Spring MVC 和 Spring WebFlux 仅在其为名为 applicationTaskExecutorAsyncTaskExecutor 实现时才会使用。 根据您的目标安排,您可以将 Executor 更改为 AsyncTaskExecutor,或同时定义一个 AsyncTaskExecutor 和一个包装自定义 ExecutorAsyncConfigurer

自动配置的 ThreadPoolTaskExecutorBuilder 允许您轻松创建与自动配置默认行为一致的实例。

如果定义了多个 Executor bean,常规任务执行会回退到名为 taskExecutor 的 bean。 GraphQL、Spring MVC 和 Spring WebFlux 支持会回退到名为 applicationTaskExecutor 的 bean。

当自动配置 ThreadPoolTaskExecutor 时,线程池默认使用 8 个核心线程,并可根据负载增长和收缩。 这些默认设置可以通过 spring.task.execution 命名空间进行微调,如下例所示:

  • Properties

  • YAML

spring.task.execution.pool.max-size=16
spring.task.execution.pool.queue-capacity=100
spring.task.execution.pool.keep-alive=10s
spring:
  task:
    execution:
      pool:
        max-size: 16
        queue-capacity: 100
        keep-alive: "10s"

这会将线程池更改为使用有界队列,因此当队列已满(100 个任务)时,线程池会增加到最多 16 个线程。 线程池的收缩也更为积极,当线程空闲 10 秒(默认是 60 秒)时会被回收。

如果需要与定时任务执行相关联,也可以自动配置调度器(例如使用 @EnableScheduling)。

如果启用虚拟线程(使用 Java 21+ 且 spring.threads.virtual.enabled 设置为 true),这将是一个使用虚拟线程的 SimpleAsyncTaskScheduler。 此 SimpleAsyncTaskScheduler 会忽略所有与池相关的属性。

如果未启用虚拟线程,则会是一个带有合理默认值的 ThreadPoolTaskSchedulerThreadPoolTaskScheduler 默认使用一个线程,其设置可通过 spring.task.scheduling 命名空间进行微调,如下例所示:

  • Properties

  • YAML

spring.task.scheduling.thread-name-prefix=scheduling-
spring.task.scheduling.pool.size=2
spring:
  task:
    scheduling:
      thread-name-prefix: "scheduling-"
      pool:
        size: 2

如果需要创建自定义执行器或调度器,ThreadPoolTaskExecutorBuilderSimpleAsyncTaskExecutorBuilderThreadPoolTaskSchedulerBuilderSimpleAsyncTaskSchedulerBuilder bean 都会在上下文中可用。 SimpleAsyncTaskExecutorBuilderSimpleAsyncTaskSchedulerBuilder bean 会在启用虚拟线程时自动配置为使用虚拟线程(使用 Java 21+ 且 spring.threads.virtual.enabled 设置为 true)。