前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot定时任务源码分析

SpringBoot定时任务源码分析

作者头像
CBeann
发布2023-12-25 19:14:34
1170
发布2023-12-25 19:14:34
举报
文章被收录于专栏:CBeann的博客CBeann的博客

写作目的

最近看了一篇博客 “Spring Boot实现定时任务的动态增删启停” ,其实实现这个需求的前提是你要搞明白 定时任务 的实现原理,这样你才有可能实现定时任务的动态增删启停,所以下面从源码的角度跟 SpringBoot定时任务原理。

代码下载

https://gitee.com/cbeann/Demooo/tree/master/springboot-demo/src/main/java/com/example/scheduledemo

源码分析

引入@EnableScheduling注解做了什么?

我们打开@EnableScheduling注解源码后发现

代码语言:javascript
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {

}

其实改注解同Import引入了一个类SchedulingConfiguration类,该类向IOC容器中注入了一个BeanPostProcessor:ScheduledAnnotationBeanPostProcessor

代码语言:javascript
复制
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {

	@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
		return new ScheduledAnnotationBeanPostProcessor();
	}

}

总结:@EnableScheduling 该类向IOC容器中注入了一个BeanPostProcessor:ScheduledAnnotationBeanPostProcessor

ScheduledAnnotationBeanPostProcessor初始化做了什么?

代码语言:javascript
复制
public ScheduledAnnotationBeanPostProcessor() {
		this.registrar = new ScheduledTaskRegistrar();
	}

总结:就如代码所示,new一个ScheduledTaskRegistrar

TaskComponent(自定义类)生命周期中ScheduledAnnotationBeanPostProcessor做了什么?

下图是ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization方法的源码,第一个方框就是把带有Scheduled注解的方法找出来,第二个方框是对每一个方法执行processScheduled逻辑。

在这里插入图片描述
在这里插入图片描述

下面截取ScheduledAnnotationBeanPostProcessor.processScheduled方法里的部分代码,它会把方法放到ScheduledTaskRegistrar里(ScheduledAnnotationBeanPostProcessor无参构造方法new的对象)

在这里插入图片描述
在这里插入图片描述

什么时候开始启动定时任务呢?

我们先详细看一下ScheduledAnnotationBeanPostProcessor的实现的接口和类,其实它实现了ApplicationListener,其实ScheduledAnnotationBeanPostProcessor也是一个监听器

代码语言:javascript
复制
public class ScheduledAnnotationBeanPostProcessor
		implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor,
		Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware,
		SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean 

那就有点门路了,最后肯定会调用ApplicationListener实现类(ScheduledAnnotationBeanPostProcessor)的某些方法,

在这里插入图片描述
在这里插入图片描述

最后其实跟下去,你就会发现他调用了ScheduledAnnotationBeanPostProcessor里ScheduledTaskRegistrar的scheduleTasks方法

代码语言:javascript
复制
protected void scheduleTasks() {
		if (this.taskScheduler == null) {
			this.localExecutor = Executors.newSingleThreadScheduledExecutor();
			this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
		}
		if (this.triggerTasks != null) {
			for (TriggerTask task : this.triggerTasks) {
				addScheduledTask(scheduleTriggerTask(task));
			}
		}
		if (this.cronTasks != null) {
			for (CronTask task : this.cronTasks) {
				addScheduledTask(scheduleCronTask(task));
			}
		}
		if (this.fixedRateTasks != null) {
			for (IntervalTask task : this.fixedRateTasks) {
				addScheduledTask(scheduleFixedRateTask(task));
			}
		}
		if (this.fixedDelayTasks != null) {
			for (IntervalTask task : this.fixedDelayTasks) {
				addScheduledTask(scheduleFixedDelayTask(task));
			}
		}
	}

然后就开始执行了

总结

思路

通过@EnableScheduling注解添加一个ScheduledAnnotationBeanPostProcessor,在Bean生命周期里拦截方法看是否有@Scheduled注解,如果有,把方法存到ScheduledAnnotationBeanPostProcessor里的ScheduledTaskRegistrar里。同时ScheduledAnnotationBeanPostProcessor又是linstener,最后ioc容器加载完毕后会通知linstener,然后就调用ScheduledAnnotationBeanPostProcessor里ScheduledTaskRegistrar的里存的方法去按照一定的逻辑去执行,就实现了以上逻辑。

总结

其实SpringBoot的自动装配原理也查不多,通过注解引入某个类(大多包含BeanPostProcessor),然后根据注解拦截Bean生命周期,把方法放在某个地方,然后最后通过监听器或者Runner去开启某个新功能。

参考

https://mp.weixin.qq.com/s/7deN_VIp3f9k1fRXsZS4NQ

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写作目的
  • 代码下载
  • 源码分析
    • 引入@EnableScheduling注解做了什么?
      • ScheduledAnnotationBeanPostProcessor初始化做了什么?
        • TaskComponent(自定义类)生命周期中ScheduledAnnotationBeanPostProcessor做了什么?
          • 什么时候开始启动定时任务呢?
          • 总结
            • 思路
              • 总结
              • 参考
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档