Spring任务调度&异步任务&Web异步请求三者如何配置线程池?

2023年 8月 5日 21.7k 0

一、任务调度

注解类:@Scheduled

核心处理类:ScheduledAnnotationBeanPostProcessor

使用的线程池:从容器中查询TaskScheduler。

  • 首先在容器中通过类型查找TaskScheduler Bean,如果没有则抛出NoSuchBeanDefinitionException异常。
  • 在这一步中,如果找到多个,那么会在通过beanName=taskScheduler在容器中查找
  • 在上一步中抛出异常后会继续查找java.util.concurrent.ScheduledExecutorService 类型的Bean。
  • 在这一步中,如果找到多个,那么会在通过beanName=taskScheduler在容器中查找
  • 在上一步中还是没有则结束(程序并不会报错)

如果上面流程都没有找到,则会通过如下方式创建一个。

this.localExecutor = Executors.newSingleThreadScheduledExecutor();
 this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);

在Springboot中有个自动配置类会配置一个TaskSchedulingAutoConfiguration。

public class TaskSchedulingAutoConfiguration {
   @Bean
   @ConditionalOnBean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
   @ConditionalOnMissingBean({ SchedulingConfigurer.class, TaskScheduler.class, ScheduledExecutorService.class })
   public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {
     return builder.build();
   }
   
   @Bean
   @ConditionalOnMissingBean
   public TaskSchedulerBuilder taskSchedulerBuilder(TaskSchedulingProperties properties,
       ObjectProvider taskSchedulerCustomizers) {
     TaskSchedulerBuilder builder = new TaskSchedulerBuilder();
     builder = builder.poolSize(properties.getPool().getSize());
     Shutdown shutdown = properties.getShutdown();
     builder = builder.awaitTermination(shutdown.isAwaitTermination());
     builder = builder.awaitTerminationPeriod(shutdown.getAwaitTerminationPeriod());
     builder = builder.threadNamePrefix(properties.getThreadNamePrefix());
     builder = builder.customizers(taskSchedulerCustomizers);
     return builder;
   }
 }

二、异步任务

  • 注解类:Async。
  • 核心处理类:AsyncAnnotationBeanPostProcessor。

通过ProxyAsyncConfiguration配置,该类继承AbstractAsyncConfiguration。

在父类中会初始化,下面两个成员变量:

@Configuration(proxyBeanMethods = false)
 public abstract class AbstractAsyncConfiguration implements ImportAware {
   @Nullable
   protected Supplier executor;
   @Nullable
   protected Supplier exceptionHandler;
   // 在容器中查找AsyncConfigurer Bean 且只能有一个
   @Autowired
   void setConfigurers(ObjectProvider configurers) {
     Supplier configurer = SingletonSupplier.of(() -> {
       List candidates = configurers.stream().collect(Collectors.toList());
       if (CollectionUtils.isEmpty(candidates)) {
         return null;
       }
       if (candidates.size() > 1) {
         throw new IllegalStateException("Only one AsyncConfigurer may exist");
       }
       return candidates.get(0);
     });
     this.executor = adapt(configurer, AsyncConfigurer::getAsyncExecutor);
     this.exceptionHandler = adapt(configurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
   }
 
   private  Supplier adapt(Supplier supplier, Function provider) {
     return () -> {
       AsyncConfigurer configurer = supplier.get();
       return (configurer != null ? provider.apply(configurer) : null);
     };
   }
 }

使用的线程池:

  • 首先在容器中通过类型查找AsyncConfigurer Bean。
  • 如果没有则设置默认的AsyncConfigurer::getAsyncExecutor 该方法是接口中默认方法,返回的是null。
  • 在上一步中如果容器中没有AsyncConfigurer,那么设置到AsyncAnnotationBeanPostProcessor中也将就是null。
  • 初始化AsyncAnnotationBeanPostProcessor。
public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor {
@Nullable
private Supplier executor;
@Nullable
private Supplier exceptionHandler;
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
// 构建切面Advisor
AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
if (this.asyncAnnotationType != null) {
advisor.setAsyncAnnotationType(this.asyncAnnotationType);
}
advisor.setBeanFactory(beanFactory);
this.advisor = advisor;
}
}
public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
public AsyncAnnotationAdvisor(
@Nullable Supplier executor, @Nullable Supplier exceptionHandler) {

Set

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论