@Scheduled和@SchedulerLock原理 - ambition0802/spring-practice GitHub Wiki

@Scheduled
  1. ScheduledAnnotationBeanPostProcessor.java 的postProcessorAfterInitialization方法中扫描bean的所有方法,查看bean方法有无@Scheduled注解。

  2. @Scheduled有多种配置,initialDelay、cron、fixedDelay、fixedRate,不同的定时配置,通过org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor#registrar(ScheduledTaskRegistrar)的不同方法去注册执行。

    比如fixedDelay通过registrar的scheduleFixedDelayTask方法将定时任务注册到registrar的fixedDelayTasks(List)中。

  3. registrar实现了InitializingBean接口,在InitializingBean接口的afterPropertiesSet方法中(其实是被onApplication调用的,不是因为InitializingBean调用的?),遍历fixedDelayTasks中注册的fixedDelay任务,最终通过JUC包下的ScheduledThreadPoolExecutor来执行定时任务。

@SchedulerLock

  1. 由shedlock组件实现:

    		<dependency>
    			<groupId>net.javacrumbs.shedlock</groupId>
    			<artifactId>shedlock-spring</artifactId>
    			<version>2.5.0</version>
    		</dependency>
    		<dependency>
    			<groupId>net.javacrumbs.shedlock</groupId>
    			<artifactId>shedlock-provider-jdbc-template</artifactId>
    			<version>2.5.0</version>
    		</dependency>		
  2. @SchedulerLock通过ScheduledTaskRegistrar和Spring的@Scheduled进行集成,shedlock将自己的LockableTaskScheduler注入到Spring容器中(具体过程?),ScheduledTaskRegistrar将自己的TaskScheduler设置成LockableTaskScheduler

  3. 在@Scheduled的第3步骤中,LockableTaskScheduler在scheduleWithFixedDelay方法中将task包装成LockableRunnable.

  4. 在LockableRunnable的run方法中,使用LockingTaskExecutor去真正执行任务,在执行开始的时候,判断有没有配置shedlock,如果由,就走shedlock的分布式锁的逻辑。如果没有就和正常的@Scheduled任务一样运行。

  5. shedlock的分布式锁依赖于单点数据库实现,shedlock需要拿到数据库的DataSource。shedlock使用LockProvider包装DataSource,所以插件内要连接数据库,只要在插件容器中创建支持vt-web的DataSource的LockProvider Bean就可以了。

关于@EnableSchduling

vt-web中启用@Scheduled,使用的是@EnableSchduling注解,实际上@EnableSchduling注解是通过@Import注解引入了ScheduleingConfiguration,ScheduleingConfiguration再往容器中添加ScheduledAnnotationBeanPostProcessor实例(即bean)。

@EnableSchduling需要和@Configuration配和使用。在处理被@Configuration注解的类的时候,会去找这个类上面的@Import注解,从而将@Import注解中指定的类(ScheduleingConfiguration)加载进来。ScheduleingConfiguration加载进来后通过@Bean创建ScheduledAnnotationBeanPostProcessor。

⚠️ **GitHub.com Fallback** ⚠️