写作目的
最近看了一篇博客 “Spring Boot实现定时任务的动态增删启停” ,其实实现这个需求的前提是你要搞明白 定时任务 的实现原理,这样你才有可能实现定时任务的动态增删启停,所以下面从源码的角度跟 SpringBoot定时任务原理。
代码下载
https://gitee.com/cbeann/Demooo/tree/master/springboot-demo/src/main/java/com/example/scheduledemo
源码分析
引入@EnableScheduling注解做了什么?
我们打开@EnableScheduling注解源码后发现
其实改注解同Import引入了一个类SchedulingConfiguration类,该类向IOC容器中注入了一个BeanPostProcessor:ScheduledAnnotationBeanPostProcessor
总结:@EnableScheduling 该类向IOC容器中注入了一个BeanPostProcessor:ScheduledAnnotationBeanPostProcessor
ScheduledAnnotationBeanPostProcessor初始化做了什么?
总结:就如代码所示,new一个ScheduledTaskRegistrar
TaskComponent(自定义类)生命周期中ScheduledAnnotationBeanPostProcessor做了什么?
下图是ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization方法的源码,第一个方框就是把带有Scheduled注解的方法找出来,第二个方框是对每一个方法执行processScheduled逻辑。
下面截取ScheduledAnnotationBeanPostProcessor.processScheduled方法里的部分代码,它会把方法放到ScheduledTaskRegistrar里(ScheduledAnnotationBeanPostProcessor无参构造方法new的对象)
什么时候开始启动定时任务呢?
我们先详细看一下ScheduledAnnotationBeanPostProcessor的实现的接口和类,其实它实现了ApplicationListener,其实ScheduledAnnotationBeanPostProcessor也是一个监听器。
那就有点门路了,最后肯定会调用ApplicationListener实现类(ScheduledAnnotationBeanPostProcessor)的某些方法,
最后其实跟下去,你就会发现他调用了ScheduledAnnotationBeanPostProcessor里ScheduledTaskRegistrar的scheduleTasks方法
然后就开始执行了
总结
思路
通过@EnableScheduling注解添加一个ScheduledAnnotationBeanPostProcessor,在Bean生命周期里拦截方法看是否有@Scheduled注解,如果有,把方法存到ScheduledAnnotationBeanPostProcessor里的ScheduledTaskRegistrar里。同时ScheduledAnnotationBeanPostProcessor又是linstener,最后ioc容器加载完毕后会通知linstener,然后就调用ScheduledAnnotationBeanPostProcessor里ScheduledTaskRegistrar的里存的方法去按照一定的逻辑去执行,就实现了以上逻辑。
总结
其实SpringBoot的自动装配原理也查不多,通过注解引入某个类(大多包含BeanPostProcessor),然后根据注解拦截Bean生命周期,把方法放在某个地方,然后最后通过监听器或者Runner去开启某个新功能。