文章目录
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();
}