spring源码------`@Schedule`跟`@Schedules`注解实现定时任务的原理

1.@Scheduled@EnableScheduling

1.1 @Scheduled注解

 Spring在3.0版本的时候加入@Scheduled注解来完成对定时任务的支持,其底层是spring自己实现的一套定时任务的逻辑,所以功能比价简单,但是能够实现单机部署上的定时任务。这里对这个注解的内部的属性进行分析。

@Target({
   ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
   

	//一个特殊的cron表达式,表示的是禁用Trigger
	String CRON_DISABLED = ScheduledTaskRegistrar.CRON_DISABLED;

	//cron表达式
	String cron() default "";

	//时区 默认是的是取当前的服务器的时区
	String zone() default "";

	//在任务最后一次调用的结束和下一次调用的开始之间以毫秒为单位执行带注释的方法
	long fixedDelay() default -1;

	//在最后一次调用的结束和下一次调用的开始之间以毫秒为单位执行带注释的方法
	String fixedDelayString() default "";

	//在两次调用之间以毫秒为单位执行带注释的方法。
	long fixedRate() default -1;

	//在两次调用之间以毫秒为单位执行带注释的方法。
	String fixedRateString() default "";

	//在第一次执行任务之前延迟多少秒
	long initialDelay() default -1;

	//在第一次执行任务之前延迟多少秒
	String initialDelayString() default "";

}

 在@Scheduled注解中主要定了定时任务相关的属性,包含的常用的cron表达式,还添加了其他的属性。可以指定是否使用触发器(Tigger),可以使用触发器的方式(注意使用触发器的方式的时候)
 在spring中还有另外的一个注解跟@Scheduled注解一样的作用,就是@Schedules注解,这个注解内部包含多个@Scheduled注解,可以表示一个方法可以存在多个调度设置

@Target({
   ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Schedules {
   

	Scheduled[] value();

}
1.2 @EnableScheduling注解

@EnableScheduling注解是spring在3.1版本的时候加上的,作用就是开启spring对定时任务的支持。这个注解也是对@Import注解的一个扩展使用。关于@Import注解可以看看前面的一篇文章spring源码解析------@Import注解解析与ImportSelector,ImportBeanDefinitionRegistrar以及DeferredImportSelector区别进行了解。

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

}

2 @Scheduled@EnableScheduling注解的解析

 基于对@Import注解的了解,这里直接进入到@EnableScheduling注解上面指定的SchedulingConfiguration类进行查看。

2.1 开启定时任务入口的SchedulingConfiguration

 在SchedulingConfiguration中代码很少,只是注册了一个bean到容器中。但是这个bean却是定时任务的解析与创建的核心类。进入到代码中查看

@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {
   

	@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
   
		//注册ScheduledAnnotationBeanPostProcessor到容器中
		return new ScheduledAnnotationBeanPostProcessor();
	}
}

 这里的代码不用进行解析了,只是进行了一个注解,接下来的才是重要的东西。

2.2 解析@Scheduled@Schedules以及创建定时任务入口的ScheduledAnnotationBeanPostProcessor

 在解析ScheduledAnnotationBeanPostProcessor之前,我们需要先了解一下bean的生命周期最好了。因为这个类继承了实现了很多的spring的生命周期相关的接口,关于spring 的生命周期相关的可以看看Spring源码----Spring的Bean生命周期流程图及代码解释,现在进行下一步的解析。

2.2.1 ScheduledAnnotationBeanPostProcessor实现的生命周期的方法排序

 这里先吧ScheduledAnnotationBeanPostProcessor实现与继承的接口展示出来,然后说明主要的实现方法的调用顺序。

public class ScheduledAnnotationBeanPostProcessor
		implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor,
		Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware,
		SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean {
   
	......
	@Override
	//实现Ordered接口,返回当前BeanPostProcessor的顺序
	public int getOrder() {
   
		return LOWEST_PRECEDENCE;
	}
	......
	@Override
	//实现EmbeddedValueResolverAware接口
	public void setEmbeddedValueResolver(StringValueResolver resolver) {
   
		//设置string字段解析的对象StringValueResolver
		this.embeddedValueResolver = resolver;
	}

	@Override
	//实现BeanNameAware接口
	public void setBeanName(String beanName) {
   
		this.beanName = beanName;
	}
	
	@Override
	//实现BeanFactoryAware接口
	public void setBeanFactory(BeanFactory beanFactory) {
   
		this.beanFactory = beanFactory;
	}
	
	@Override
	//实现ApplicationContextAware接口
	public void setApplicationContext(ApplicationContext applicationContext) {
   
		//设置spring的上下文进来
	this.applicationContext = applicationContext;
		if (this.beanFactory == null) {
   
			this.beanFactory = applicationContext;
		}
	}
	
	@Override
	//实现了SmartInitializingSingleton接口,在所有的单例bean实例化之后
	public void afterSingletonsInstantiated() {
   
		// Remove resolved singleton classes from cache
		//移除缓存
		this.nonAnnotatedClasses.clear();

		if (this.applicationContext == null) {
   
			// Not running in an ApplicationContext -> register tasks early...
			// 不再上下文中运行,这里表示的是spring的上下文还没有初始化完成时候调用,一般都不会进入到这里
			finishRegistration();
		}
	}

	@Override
	//实现了ApplicationListener,这里监听的是上下文刷新完成事件
	public void onApplicationEvent(ContextRefreshedEvent event) {
   
		if (event.getApplicationContext() == this.applicationContext) {
   
			// Running in an ApplicationContext -> register tasks this late...
			// giving other ContextRefreshedEvent listeners a chance to perform
			// their work at the same time (e.g. Spring Batch's job registration).
			//注册定时任务
			finishRegistration();
		}
	}
	
	@Override
	//实现了MergedBeanDefinitionPostProcessor,这里是空实现的,
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
   
	}

	@Override
	//这里实现BeanPostProcessor,也是空实现,在bean初始化之前
	public Object postProcessBeforeInitialization(Object bean, String beanName) {
   
		return bean;
	}

	@Override
	//实现BeanPostProcessor,在bean初始化之后
	public Object postProcessAfterInitialization(Object bean, String beanName) {
   
		......
	}

	@Override
	//实现了DestructionAwareBeanPostProcessor,bean销毁之前调用
	public void postProcessBeforeDestruction(Object bean, String beanName) {
   
		Set<ScheduledTask> tasks;
		synchronized (this.scheduledTasks) {
   
			tasks = this.scheduledTasks.remove(bean);
		}
		if (tasks != null) {
   
			for (ScheduledTask task : tasks) {
   
				task.cancel();
			}
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值