成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring任務調度&異步任務&Web異步請求三者如何配置線程池?

開發 前端
首先在容器中通過類型查找TaskScheduler Bean,如果沒有則拋出NoSuchBeanDefinitionException異常。在這一步中,如果找到多個,那么會在通過beanName=taskScheduler在容器中查找。

一、任務調度

注解類:@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<TaskSchedulerCustomizer> 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> executor;
   @Nullable
   protected Supplier<AsyncUncaughtExceptionHandler> exceptionHandler;
   // 在容器中查找AsyncConfigurer Bean 且只能有一個
   @Autowired
   void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
     Supplier<AsyncConfigurer> configurer = SingletonSupplier.of(() -> {
       List<AsyncConfigurer> 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 <T> Supplier<T> adapt(Supplier<AsyncConfigurer> supplier, Function<AsyncConfigurer, T> 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> executor;
   @Nullable
   private Supplier<AsyncUncaughtExceptionHandler> 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> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
 
     Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
     asyncAnnotationTypes.add(Async.class);
     try {
       asyncAnnotationTypes.add((Class<? extends Annotation>)
           ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
     }
     // 構建通知類
     this.advice = buildAdvice(executor, exceptionHandler);
     this.pointcut = buildPointcut(asyncAnnotationTypes);
   }
   protected Advice buildAdvice(
       @Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
 
     AnnotationAsyncExecutionInterceptor interceptor = new AnnotationAsyncExecutionInterceptor(null);
     // 調用父類方法
     interceptor.configure(executor, exceptionHandler);
     return interceptor;
   }
 }
 public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware { 
   public void configure(@Nullable Supplier<Executor> defaultExecutor,
       @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
 
     // 如果defaultExecutor則調用getDefaultExecutor方法,該方法在子類重寫了
     this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
     this.exceptionHandler = new SingletonSupplier<>(exceptionHandler, SimpleAsyncUncaughtExceptionHandler::new);
   }
   protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
     if (beanFactory != null) {
       try {
         // 容器中查找TaskExecutor類型的Bean
         return beanFactory.getBean(TaskExecutor.class);
       } catch (NoUniqueBeanDefinitionException ex) {
         try {
           return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
         } catch (NoSuchBeanDefinitionException ex2) {
         }
       } catch (NoSuchBeanDefinitionException ex) {
         try {
           return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
         } catch (NoSuchBeanDefinitionException ex2) {
         }
         // Giving up -> either using local default executor or none at all...
       }
     }
     return null;
   }
 }
 public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor, Ordered {
   protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
     // 先通過父類獲取
     Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
     // 如果父類獲取不到,則創建默認的SimpleAsyncTaskExecutor
     return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
   }
 }

總結:

  • 從容器中查找TaskExecutor Bean。
  • 上一步沒有找到,則查找beanName=taskExecutor,類型為java.util.concurrent.Executor的Bean。
  • 如果上一步還是沒有找到,那么最終創建默認的SimpleAsyncTaskExecutor 這是個沒有上限的線程池,來一個任務創建新線程。

如果執行的異步任務很多且線程池,線程有限則多的任務會等待。

三、Web異步接口

RequestMappingHandlerAdapter。

public class RequestMappingHandlerAdapter {
   // 默認是一個沒有上限的線程池
   private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("MvcAsync");
   protected ModelAndView invokeHandlerMethod(
     HttpServletRequest request,
     HttpServletResponse response, 
     HandlerMethod handlerMethod) throws Exception {
     // ...
     WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
     asyncManager.setTaskExecutor(this.taskExecutor);
     // ...
   }
 }

創建RequestMappingHandlerAdapter Bean對象。

繼承關系。

public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration{}
 public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
   private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
   // WebMvcConfigurer默認實現
   @Autowired(required = false)
   public void setConfigurers(List<WebMvcConfigurer> configurers) {
     if (!CollectionUtils.isEmpty(configurers)) {
       this.configurers.addWebMvcConfigurers(configurers);
     }
   }
   @Override
   protected void configureAsyncSupport(AsyncSupportConfigurer configurer) {
     this.configurers.configureAsyncSupport(configurer);
   }
 }
 public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
   private AsyncSupportConfigurer asyncSupportConfigurer;
   @Bean
   public RequestMappingHandlerAdapter requestMappingHandlerAdapter(...) {
     // ...
     AsyncSupportConfigurer configurer = getAsyncSupportConfigurer();
     if (configurer.getTaskExecutor() != null) {
       adapter.setTaskExecutor(configurer.getTaskExecutor());
     }
     // ...
   }
   protected AsyncSupportConfigurer getAsyncSupportConfigurer() {
     if (this.asyncSupportConfigurer == null) {
       this.asyncSupportConfigurer = new AsyncSupportConfigurer();
       configureAsyncSupport(this.asyncSupportConfigurer);
     }
     return this.asyncSupportConfigurer;
   }
 }
 public class WebMvcAutoConfiguration {
   public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
     public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
       // 判斷容器中是否有beanName = applicationTaskExecutor 的Bean
       if (this.beanFactory.containsBean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)) {
         // 通過beanName = applicationTaskExecutor獲取bean對象
         Object taskExecutor = this.beanFactory.getBean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME);
         // 判斷是否AsyncTaskExecutor對象
         if (taskExecutor instanceof AsyncTaskExecutor) {
           configurer.setTaskExecutor(((AsyncTaskExecutor) taskExecutor));
         }
       }
       Duration timeout = this.mvcProperties.getAsync().getRequestTimeout();
       if (timeout != null) {
         configurer.setDefaultTimeout(timeout.toMillis());
       }
     }
   }
 }

總結:

  • 默認使用SimpleAsyncTaskExecutor。
  • 如果容器中存在以beanName = applicationTaskExecutor 且 類型是 AsyncTaskExecutor, 則使用該bean。

到這你應該知道了這三者在線程池方面該如何正確配置及使用了。

責任編輯:姜華 來源: 今日頭條
相關推薦

2024-10-14 13:12:59

2020-07-02 07:44:27

Spring教程異步

2014-04-24 09:49:57

Android測試異步任務

2021-11-01 22:36:04

JavaScript

2024-02-28 09:54:07

線程池配置

2023-12-29 09:38:00

Java線程池

2023-08-02 08:03:08

Python線程池

2023-01-03 10:38:04

函數計算技術

2022-06-02 10:18:24

函數計算異步

2021-08-16 15:49:31

開發框架單線程異步

2024-06-13 00:54:19

2023-11-03 14:32:38

2025-05-08 08:00:00

FastAPI開發異步定時

2023-12-26 07:44:00

Spring定時調度

2021-05-13 12:00:51

cron調度任務系統運維

2014-12-24 10:00:07

Spring

2024-07-31 15:57:41

2024-10-15 10:28:43

2023-08-04 11:04:03

線程池項目開發

2024-09-09 15:09:30

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 婷婷久久精品一区二区 | 日日骚网 | 91精品国产91久久久久久 | 欧美久久久久久 | 婷婷二区 | 伊人久久免费视频 | 2020国产在线 | 欧洲精品在线观看 | 爱爱免费视频 | 2019天天干天天操 | 国产精品久久久久无码av | 国产福利资源在线 | 日本成人一区二区 | 精品日本中文字幕 | 日韩一级 | 亚洲一区国产 | 久久av网| av一区二区三区四区 | 日韩在线不卡 | 国产福利在线免费观看 | 成人免费av在线 | 日韩免费av| 中文字幕在线精品 | 国产成人久久精品一区二区三区 | 久久久久亚洲 | 亚洲草草视频 | 久久91| 日韩精品av一区二区三区 | 日韩午夜场 | 国产xxx在线观看 | 西西裸体做爰视频 | 国产精品99一区二区 | 91av在线免费看 | 色吧色综合 | 一级做a爰片性色毛片16美国 | 久久精品国产亚洲一区二区三区 | 亚洲欧美在线一区 | 日本一区二区三区在线观看 | 久久亚洲一区 | 亚洲精品成人 | 男人av网 |