Task Scheduler实现剖析
- 1. 添加@EnableScheduling
- 2. ScheduledAnnotationBeanPostProcessor
- 3. 任务调度的主要逻辑
-
- 3.1 扫描@Scheduled注解方法生成任务
- 3.2 清空任务生成过程中产生的缓存
- 3.3 通过TaskScheduler调度任务
- 4. 通过SchedulingConfigurer方式注册TaskScheduler
- 参考
1. 添加@EnableScheduling
添加该注解的作用主要是引入SchedulingConfiguration类,该类是一个JavaConfig类,注册了一个BeanPostProcessor类org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor。接下来重点看一下这个BeanPostProcessor类都做了哪些事情。
代码语言:javascript复制@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
}
2. ScheduledAnnotationBeanPostProcessor
该类实现接口较多,参考下图:
3. 任务调度的主要逻辑
3.1 扫描@Scheduled注解方法生成任务
核心方法ScheduledAnnotationBeanPostProcessor#postProcessAfterInitialization,该方法在每个bean初始化完成后调用。
主要逻辑判定当前bean是否有@Scheduled注解的方法,如果存在则创建相应的任务并触发。
3.2 清空任务生成过程中产生的缓存
核心方法ScheduledAnnotationBeanPostProcessor#afterSingletonsInstantiated,该方法在所有单例Bean初始化完成后执行。
主要作用是清空没有@Scheduled注解的类的缓存信息。
3.3 通过TaskScheduler调度任务
核心方法ScheduledAnnotationBeanPostProcessor#onApplicationEvent,该方法在ApplicationContext更新完毕后,通过ContextRefreshedEvent事件触发。
其主要作用是获取taskScheduler,获取taskScheduler的逻辑: 1、是否存在实现SchedulingConfigurer接口的Bean,如果存在则通过SchedulingConfigurer的实现Bean注册调度器(Scheduler)。 2、查看是否有名称为taskScheduler、类型为org.springframework.scheduling.TaskScheduler或java.util.concurrent.ScheduledExecutorService的bean。
任务调度默认使用的是org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler。 该类通过org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration自动配置类加载。
可以通过配置文件修改线程池大小和线程池前缀等信息。
代码语言:javascript复制spring:
task:
scheduling:
thread-name-prefix: sbia-schedule-
pool:
size: 4
PS: 以上内容spring-boot-2.1.5.RELEASE,1.5.9.RELEASE版本中没有TaskSchedulingAutoConfiguration自动配置类,默认taskScheduler的值如下:
代码语言:javascript复制if (this.taskScheduler == null) {
this.localExecutor = Executors.newSingleThreadScheduledExecutor();
this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
}
4. 通过SchedulingConfigurer方式注册TaskScheduler
通过该方法可以注册org.springframework.scheduling.TaskScheduler和java.util.concurrent.ScheduledExecutorService类型的调度器。
代码语言:javascript复制/** * 通过该方式设置的Scheduler,默认使用org.springframework.scheduling.concurrent.ConcurrentTaskScheduler */
@Component
public class SbiaSchedulingConfigurer implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
r -> new Thread(r, "sbia-schedule-")));
}
}
参考
@Scheduled不生效了:有一天我的定时任务突然不执行了
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183170.html原文链接:https://javaforall.cn