携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情
前言
在上一篇文章中简单说明了在springboot项目中如何实现一个定时任务,在此之外,还有其他种方式实现,先来看一下springtask的实现原理。
分析
先来回忆一下,要实现定时任务的两个步骤:
- 在启动类上加@EnableScheduling,开启定时任务功能
- 在被spring管理的bean中加入定时任务执行的方法,方法上标注@Scheduled
既然步骤只有两个,那就从这两个步骤分析。
@EnableScheduling
源码发现,注解类中主要就引入了一个
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
......
}
查看源码发现,注解类中主要就引入了一个SchedulingConfiguration类,而在中,只是注册了一个ScheduledAnnotationBeanPostProcessor实例,这是一个后置处理器(在Bean对象实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑)。
ScheduledAnnotationBeanPostProcessor主要是找出全部被@Scheduled注解标记的方法,并调用processScheduled方法
processScheduled方法主要逻辑:
- 检测被@Scheduled注解标注的方法是否有参数
- 检测被@Scheduled注解标注的方法是否是无参且无返回值
- 检测通过后使用ScheduledTaskRegistrar类注册定时任务,然后加入任务列表
ScheduledTaskRegistrar类的主要作用:
- 实现InitializingBean接口和DisposableBean接口,定义在初始化bean的时候会执行的逻辑、在bean被销毁时执行的逻辑。
- 定义执行定时任务的TaskScheduler实例、注册任务、执行定时任务、返回当前实例的任务列表
@Scheduled
知道了@EnableScheduling 注解的作用后,就知道为什么在方法上加入一个@Schedule注解后就能实现定时任务了,因为在应用程序启动时就会把方法作为任务注册到TaskSchedule中,然后由ConcurrentTaskScheduler执行。