SpringBoot定时任务源码分析

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

代码下载


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


源码分析


引入@EnableScheduling注解做了什么?


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


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
}


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


@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初始化做了什么?


public ScheduledAnnotationBeanPostProcessor() {
    this.registrar = new ScheduledTaskRegistrar();
  }


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


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


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


7.png


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


8.png


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


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


public class ScheduledAnnotationBeanPostProcessor
    implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor,
    Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware,
    SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean 


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


9.png


最后其实跟下去,你就会发现他调用了ScheduledAnnotationBeanPostProcessor里

ScheduledTaskRegistrar的scheduleTasks方法


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去开启某个新功能。


目录
相关文章
|
2月前
|
存储 Java Spring
【八】springboot整合定时任务
【八】springboot整合定时任务
24 0
|
5月前
|
SQL Java 调度
SpringBoot 整合 Quartz 定时任务框架
SpringBoot 整合 Quartz 定时任务框架
64 0
|
6月前
|
Java 关系型数据库 MySQL
SpringBoot实现定时任务
SpringBoot实现定时任务
|
9月前
|
Java 调度 数据库
|
10月前
|
Java 容器
SpringBoot 整合定时任务
SpringBoot 整合定时任务
|
11月前
|
Dubbo Java 测试技术
【SpringBoot学习笔记 十二】SpringBoot异步任务、定时任务、邮件任务
【SpringBoot学习笔记 十二】SpringBoot异步任务、定时任务、邮件任务
98 0
|
11月前
|
Java
springboot 定时任务遇到的坑
springboot 定时任务遇到的坑
165 0
|
Java BI 调度
SpringBoot——整合定时任务
SpringBoot——整合定时任务
214 0
SpringBoot——整合定时任务
5、SpringBoot2.0实现定时任务(五)
引入相关定时任务相关的依赖
65 0
5、SpringBoot2.0实现定时任务(五)
|
Java
springboot配置定时任务
springboot配置定时任务
90 0