一、注解说明。
Spring 自带的定时任务执行@Scheduled注解,可以定时的、周期性的执行一些任务。查看@Scheduled的注解可以看到有以下三种:
1.1 String cron() default “” ;

//定义一个按时间执行的定时任务,在每天1:00执行一次。
@Scheduled(cron = "0 0 1* * ?")
public void run() {//执行代码
}

参数说明:

"0 0 12 * * ?"    每天中午十二点触发
"0 15 10 ? * *"    每天早上1015触发
"0 15 10 * * ?"    每天早上1015触发
"0 15 10 * * ? *"    每天早上1015触发
"0 15 10 * * ? 2005"    2005年的每天早上1015触发
"0 * 14 * * ?"    每天从下午2点开始到259分每分钟一次触发
"0 0/5 14 * * ?"    每天从下午2点开始到255分结束每5分钟一次触发
"0 0/5 14,18 * * ?"    每天的下午2点至2556点至655分两个时间段内每5分钟一次触发
"0 0-5 14 * * ?"    每天14:0014:05每分钟一次触发
"0 10,44 14 ? 3 WED"    三月的每周三的14101444触发
"0 15 10 ? * MON-FRI"    每个周一、周二、周三、周四、周五的1015触发 

1.2 long fixedDelay() default -1;

//定义一个按一定频率执行的定时任务,每隔1分钟执行一次,延迟1秒执行@Scheduled(fixedRate = 1000 * 60,initialDelay = 1000)public void run() {//执行代码
}

1.3 long fixedRate() default -1;

//定义一个按一定频率执行的定时任务,每隔2分钟执行一次@Scheduled(fixedRate = 1000 * 120)public void run() {//执行代码
}

二、@Scheduled 执行原理说明:
简要介绍:spring在初始化bean后,通过“postProcessAfterInitialization”拦截到所有的用到“@Scheduled”注解的方法,并解析相应的的注解参数,放入“定时任务列表”等待后续处理;之后再“定时任务列表”中统一执行相应的定时任务。
2.1 依次加载所有的实现 Scheduled 注解的类方法。(具体查看 spring-context jar包)说明:

ScheduledAnnotationBeanPostProcessor继承BeanPostProcessor。
public Object postProcessAfterInitialization (final Object bean, String beanName ) {final Class<?> targetClass = AopUtils.getTargetClass(bean);ReflectionUtils. doWithMethods(targetClass, new MethodCallback() {public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {Scheduled annotation = AnnotationUtils.getAnnotation(method, Scheduled.class);if (annotation != null) {// 此处省略条件判断说明Runnable runnable = new ScheduledMethodRunnable(bean , method );boolean processedSchedule = false;String errorMessage = "Exactly one of 'cron', 'fixedDelay', or 'fixedRate' is required.";String cron = annotation.cron();if (!"" .equals(cron )) {processedSchedule = true ;if (embeddedValueResolver != null) {cron = embeddedValueResolver.resolveStringValue(cron );}cronTasks.put(runnable , cron);}long fixedDelay = annotation.fixedDelay();if (fixedDelay >= 0) {Assert. isTrue(!processedSchedule, errorMessage);processedSchedule = true ;fixedDelayTasks.put(runnable , fixedDelay );}long fixedRate = annotation.fixedRate();if (fixedRate >= 0) {Assert. isTrue(!processedSchedule, errorMessage);processedSchedule = true ;fixedRateTasks.put(runnable , fixedRate);}Assert. isTrue(processedSchedule, errorMessage);}}});return bean ;}

从这段代码中我们可以发现任务为顺序执行,先执行cron,之后再执行fixedRate。
2.2 将对应类型的定时器放入相应的“定时任务列表”中,获取scheduled类参数,之后根据参数类型、相应的延时时间、对应的时区放入不同的任务列表中

protected void processScheduled(Scheduled scheduled, Method method, Object bean) {   //获取corn类型String cron = scheduled.cron();if (StringUtils.hasText(cron)) {Assert.isTrue(initialDelay == -1, "'initialDelay' not supported for cron triggers");processedSchedule = true;String zone = scheduled.zone();//放入cron任务列表中(不执行)this.registrar.addCronTask(new CronTask(runnable, new CronTrigger(cron, timeZone)));}//执行频率类型(long类型)long fixedRate = scheduled.fixedRate();String fixedDelayString = scheduled.fixedDelayString();if (fixedRate >= 0) {Assert.isTrue(!processedSchedule, errorMessage);processedSchedule = true;//放入FixedRate任务列表中(不执行)(registrar为ScheduledTaskRegistrar)this.registrar.addFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay));}//执行频率类型(字符串类型,不接收参数计算如:600*20)String fixedRateString = scheduled.fixedRateString();if (StringUtils.hasText(fixedRateString)) {Assert.isTrue(!processedSchedule, errorMessage);processedSchedule = true;if (this.embeddedValueResolver != null) {fixedRateString = this.embeddedValueResolver.resolveStringValue(fixedRateString);}fixedRate = Long.parseLong(fixedRateString);//放入FixedRate任务列表中(不执行)this.registrar.addFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay));}
}return bean;
}

2.3:执行相应的定时任务。
说明:定时任务先执行corn,判断定时任务的执行时间,计算出相应的下次执行时间,放入线程中,到相应的时间后进行执行。之后执行按“频率”(fixedRate)执行的定时任务,直到所有任务执行结束。

protected void scheduleTasks() {//顺序执行相应的Cronif (this.cronTasks != null) {for (CronTask task : this.cronTasks) {this.scheduledFutures.add(this.taskScheduler.schedule(task.getRunnable(), task.getTrigger()));}}//顺序执行所有的“fixedRate”定时任务(无延迟,也就是说initialDelay参数为空),因为无延迟,所以定时任务会直接执行一次,执行任务完成后,会将下次执行任务的时间放入delayedExecute中等待下次执行。if (this.fixedRateTasks != null) {for (IntervalTask task : this.fixedRateTasks) {if (task.getInitialDelay() > 0) {Date startTime = new Date(now + task.getInitialDelay());this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(task.getRunnable(), startTime, task.getInterval()));}else {this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(task.getRunnable(), task.getInterval()));}}}
//顺序执行所有的“fixedRate”定时任务(有延迟,也就是说initialDelay参数不为空)if (this.fixedDelayTasks != null) {for (IntervalTask task : this.fixedDelayTasks) {if (task.getInitialDelay() > 0) {Date startTime = new Date(now + task.getInitialDelay());this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(task.getRunnable(), startTime, task.getInterval()));}else {this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(task.getRunnable(), task.getInterval()));}}}
}

2.4 接下来看下定时任务run(extends自Runnable接口)方法:
//说明:每次执行定时任务结束后,会先设置下下次定时任务的执行时间,以此来确认下次任务的执行时间。

public void run() {boolean periodic = isPeriodic();if (!canRunInCurrentRunState(periodic))cancel(false);else if (!periodic)ScheduledFutureTask.super.run();else if (ScheduledFutureTask.super.runAndReset()) {setNextRunTime();reExecutePeriodic(outerTask);}
}

备注1:从上面的代码可以看出,如果多个定时任务定义的是同一个时间,那么也是顺序执行的,会根据程序加载Scheduled方法的先后来执行。
但是如果某个定时任务执行未完成会出现什么现象呢?
答:此任务一直无法执行完成,无法设置下次任务执行时间,之后会导致此任务后面的所有定时任务无法继续执行,也就会出现所有的定时任务“失效”现象。
所以应用springBoot中定时任务的方法中,一定不要出现“死循环”、“http持续等待无响应”现象,否则会导致定时任务程序无法正常。再就是非特殊需求情况下可以把定时任务“分散”下。

Spring定时任务注解说明相关推荐

  1. Spring 定时任务 注解版

    Task类: ManageSql.Java对应代码: [java] view plain copy   package com.axb.cheney.task; import java.sql.Res ...

  2. Spring定时任务注解@Scheduled+@EnableAsync用法详解(简单说明+应用场景+demo源代码+执行过程分析)

    @Scheduled 由Spring定义,用于将方法设置为调度任务,可实现方法的周期或定时执行.想单独使用Scheduling,需引入spring-context这个依赖.spring-boot-st ...

  3. 使用轻量级Spring @Scheduled注解执行定时任务

    WEB项目中需要加入一个定时执行任务,可以使用Quartz来实现,由于项目就一个定时任务,所以想简单点,不用去配置那些Quartz的配置文件,所以就采用了Spring @Scheduled注解来实现了 ...

  4. spring @Scheduled 注解实现的定时任务 3步走

    适用场景 1) Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务. 最早的时候就是这样写定时任务的.  2) 开源的第三方框架: Quar ...

  5. Spring定时任务@scheduled多线程的使用(@Async注解)

    1.开篇 在Spring定时任务@Scheduled注解使用方式浅窥这篇文章里面提及过,spring的定时任务默认是单线程的,他在某些场景下会造成堵塞,那么如果我们想让每一个任务都起一条线程去执行呢? ...

  6. Spring定时任务@Scheduled注解使用配置方式(cron表达式、fixedRate和fixedDelay)

    Spring定时任务@Scheduled注解使用配置方式(cron表达式.fixedRate和fixedDelay) 序言: 个人推荐一个很方便的在线Cron生成器(网页版):https://qqe2 ...

  7. Spring定时任务的几种实现

    Spring定时任务的几种实现 spring框架 quartz spring spring-task 定时任务 注解 近日项目开发中需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信 ...

  8. (转)Spring定时任务的几种实现

    Spring定时任务的几种实现 博客分类: spring框架 quartzspringspring-task定时任务注解  Spring定时任务的几种实现 近日项目开发中需要执行一些定时任务,比如需要 ...

  9. 【Spring学习】spring定时任务的实现方式

    近日项目开发中需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息,借此机会整理了一下定时任务的几种实现方式,由于项目采用spring框架,所以我都将结合spring框架来介绍. 一 ...

最新文章

  1. python扫题软件_python 实现端口扫描工具
  2. 【转】基于SQL的Web系统安全防范——SQL注入漏洞
  3. python鼠标位置_用python3 返回鼠标位置的实现方法(带界面)
  4. java servlet类_[Java教程]与Servlet相关的类
  5. 客户端和服务器之间的信息结构,客户端和服务器之间的信息结构
  6. LeetCode : Intersection of Two Linked Lists
  7. 软件工程经济学作业5-7
  8. Linux快捷键的使用
  9. 移动端使用二倍图比一倍图有什么好处
  10. JavaWeb 登陆界面
  11. 莫让“浮云”遮望眼:“企业技术”才是硬道理
  12. 给IT新人的15点建议:苦逼程序员的辛酸反省与总结
  13. Clean Code 读书笔记四
  14. 数据分析项目:用户消费行为分析
  15. 树莓派声音输出设置_Raspberry Pi(树莓派)声音输出的设置
  16. 对已有apk进行重新签名
  17. 项目实训第一周2-学习系统的使用
  18. 腾讯朋友圈广告的优势有哪些?如何代理腾讯朋友圈广告?
  19. urllib库(二)parse模块:urlparse()/urlsplit(),parse_qs()/parse_qsl(),urlunparse()/urlunsplit(),urlencode()
  20. 企业网盘功能完整介绍

热门文章

  1. 老板们这些股权结构需要优化了
  2. 如何理解 ssh 三大框架
  3. xshell6 强制更新的问题(转载、亲测有效)
  4. springboot集成邮箱配置ssl或tls协议
  5. Baseline Wander Correction: 基线漂移补偿
  6. css3彩虹渐变色,css3渐变 彩虹条纹
  7. |PS内置滤镜简介|
  8. 通俗易懂聊springMVC中的handler是什么
  9. Fastdfs数据迁移方案
  10. Linux实战(一):服务器应用迁移