使用说明
- 定时器类型:
- triggerTask:触发task,继承实现Trigger#nextExecutionTime方法,设置任务触发逻辑
- cronTask:cron表达式的定时任务,
@Scheduled(cron = "*/9 * * * * ?") - fixedRateTask:固定频率执行的定时任务,
@Scheduled(fixedRate = 2 * 1000),每隔2s执行一次 - fixedDelayTask:固定延迟的Task,
@Scheduled(fixedDelay = 2 * 1000),任务完成后开始计时,2s后执行
- 自定义线程池:需要继承
SchedulingConfigurer并实现configureTasks方法,为调度器设置线程池@Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { scheduledTaskRegistrar.setTaskScheduler(new ThreadPoolTaskScheduler(....)); }
代码分析
-
主体是
ScheduledAnnotationBeanPostProcessor,大概分为三步- 构造processor:
new SchedulingConfiguration- spring方法
PostProcessorRegistrationDelegate#registerBeanPostProcessors实例化SchedulingConfiguration SchedulingConfiguration中创建ScheduledAnnotationBeanPostProcessorScheduledAnnotationBeanPostProcessor构造方法中初始化ScheduledTaskRegistrar任务调度器ScheduledTaskRegistrar中维护了各种任务的列表@Nullable private List<TriggerTask> triggerTasks; @Nullable private List<CronTask> cronTasks; @Nullable private List<IntervalTask> fixedRateTasks; @Nullable private List<IntervalTask> fixedDelayTasks; private final Map<Task, ScheduledTask> unresolvedTasks = new HashMap(16); private final Set<ScheduledTask> scheduledTasks = new LinkedHashSet(16);
- spring方法
- 扫描bean中的
@Scheduled方法并保存:ScheduledAnnotationBeanPostProcessor#postProcessAfterInitialization-
ScheduledAnnotationBeanPostProcessor继承DestructionAwareBeanPostProcessor, 实现了BeanPostProcessor#postProcessAfterInitialization后置处理器,处理@Scheduled的bean -
对于有
@Scheduled的方法,进行ScheduledAnnotationBeanPostProcessor#processScheduledannotatedMethods.forEach((method, scheduledAnnotations) -> { scheduledAnnotations.forEach((scheduled) -> { this.processScheduled(scheduled, method, bean); }); }); -
processScheduled中调用registrar调度器保存各类型任务
-
- 执行保存的定时任务:监听到
ContextRefreshedEvent后,执行onApplicationEvent方法ScheduledAnnotationBeanPostProcessor继承ApplicationListener,接收消息,执行ScheduledAnnotationBeanPostProcessor#onApplicationEvent方法- 方法中设置调度器的线程池
TaskScheduler,后续执行调度器ScheduledTaskRegistrar#scheduleTasks方法,启动任务
- 构造processor:
-
还有
ThreadPoolTaskExecutor extends ExecutorConfigurationSupport初始化
ThreadPoolTaskExecutor时实现继承方法ExecutorConfigurationSupport#afterPropertiesSet通过ThreadPoolTaskExecutor#initializeExcutor设置线程池excutor
使用总结
- 所有定时任务放在一个线程池中,线程池线程数为1,任务串行,不同的任务会阻塞影响
- 按照设定时间将任务放到延迟队列中
- 对于时效性要求高的任务最好使用线程池自己控制