目录:
- 一、"定时任务" 介绍 :
- 1.1 @EnableScheduling 注解
- 1.2 @Scheduled 注解 ( 该注解中有很多"属性" , "属性" 有很多对应的 "属性值" )
- ① cron 属性 ( 设置"定时任务" 的 "执行时机" )
- ② zone 属性 ( 设置解析"cron属性值"的时区 , 默认以"服务器所在区域"的"本地时区"来解析 "cron属性值" )
- ③ fixedDelay 属性 和 fixedDelayString 属性 ( 在上一次任务"执行完毕后" ,一旦达到执行时间 就 "继续执行"下一次任务 )
- ④ fixedRate 属性 和 fixedRateString 属性 ( 每隔一段时间,"重复执行"一次"定时任务" )
- ⑤ initialDelay 属性 和 initialDelayString 属性 ( 指定 "定时任务" "第一次执行" 之前的 "延迟时间" )
- 二、"定时任务" - 案例实现 :
作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!
该文章参考学习教材为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!(侵权可联系我,进行删除,如果雷同,纯属巧合)
- 在 实际开发中,可能会有这样一个需求,需要在每天的 某个固定时间或者每隔一段时间让程序去执行某一个任务。例如,服务器数据定时 在晚上零点备份。通常我们会使用 Spring 框架提供的 Scheduling Tasks 实现这一 定时任务 的处理。
一、“定时任务” 介绍 :
- Spring 框架 的 定时任务调度 功能支持 ① 配置 和 ② 注解 “两种方式”,Spring Boot 不仅 继承了 Spring 框架 “定时任务” 调度功能,而且可以更好地支持"注解"方式的定时任务。
- 下面将介绍几种 "定时任务调度"的相关注解,使用这些 注解 来 完成" 定时任务"。
1.1 @EnableScheduling 注解
- @EnableScheduling 注解 是 Spring 框架 提供的,该注解用在 项目启动类上 ,用于开启基于 “注解” 方式 的 定时任务。
1.2 @Scheduled 注解 ( 该注解中有很多"属性" , “属性” 有很多对应的 “属性值” )
@Scheduled 注解 同样是 Spring 框架提供的,配置"定时任务" 的 执行规则,该注解主要 用在 “定时业务方法” 上。
@Scheduled 注解提供有多个属性,”精细化配置“ 定时任务执行规则,这些 @Scheduled注解 的 “属性” 及 说明 如 下表所示 :
属性 说明 corn 类似于 cron 的 表达式,可以定制 定时任务触发的秒、分钟、小时、日、月、星期 ( 一共6位数 )。
ps :
没 “具体秒数” 时间要求下,是 "整数形式"下才开始 执行任务。zone ( 时区 ) 指定 cron 表达式 将 被解析的 “时区”。默认情况下,该属性是 空字符串( 即 使用服务器的本地时区 )。 fixedDelay ( 固定延迟 ) 表示在 上一次任务执行结束后 在 指定时间后 "继续执行" 下一次任务 (属性值为 long类型 )。
ps :
使用该属性时,启动 先 立即开始 一次 执行任务,然后再按上述要求"继续执行" 任务。fixedDelayString
( 固定延迟String )表示在 上一次任务执行结束后 在 指定时间后 “继续执行" 下一次任务 (属性值为 long类型的"字符串形式” )。 fixedRate ( 固定速率 ) 表示 每隔指定时间 "执行"一次任务 ( 属性值 为 long类型 )。
ps :
使用该属性时,启动 先 立即开始 一次 执行任务,然后再按上述要求"继续执行" 任务。fixedRateString
( 固定速率String )表示 每隔指定时间 “执行"一次任务 ( 属性值 为 long类型 的 " 字符串形式” )。 initialDelay ( 初始延迟 ) 表示在 fixedRate 或 fixedDelay 任务 第一次执行之前 要 延迟的毫秒数 ( 属性值 为 long 类型 ) 。 initialDelayString
( 初始延迟String )表示在 fixedRate 或 fixedDelay 任务 第一次执行之前 要 延迟的毫秒数 ( 属性值 为 long类型的 "字符串形式" ) 。
① cron 属性 ( 设置"定时任务" 的 “执行时机” )
cron 属性 是 @Scheduled 定时任务注解中最常用也是最复杂的一个属性 ,其 属性值由类似于 cron 表达式的 6位数组成,可以详细地指定定时任务执行的秒、分、小时、日、月、星期 ( 设置 "定时任务"触发的 六位数)。示例代码如下 :
/** * 0 * * * * MON-FRI : * 第一位表示: 秒 , 第二位表示: 分 , 第三位表示: 时(小时) * 第四位表示: 日 , 第五位表示: 月 , 第六位表示: 星期 * *代表 "任意时刻" * MON-FRI : 周一到周五" * * 0 * * * * MON-FRI : 表示周一到周五"每一分钟"执行一次定时任务 */ @Scheduled(cron="0 * * * * MON-FRI") //"定时任务"注解
除此之外,cron 属性值 中的 每一位 "字段"还 支持非常丰富 的 “字段值” ,该 字段值可以是常见的" 可取值",也可以是的"特殊字符" ( 一般是两者结合使用 ),具体说明
如 下表所示 ( corn属性 的"字段值" 介绍 ):
字段 可取值 允许 的 “特殊字符” ( 也属于 “可取值的值” ) 秒 0~59 , - * / 分 0~59 , - * / 时 0-23 , - * / 日 1~31 , - * / ? L 月 1~12、月份对应 英文 “前3个” 字母 ( 大小写均可 )。 , - * / 星期 0~7 ( 0 和 7 表示 SUN )、星期 对应 英文 “前3个” 字母 ( 大小写均可 )。 , - * / ? L 上表中列举了 @Schedule 注解中 cron 属性 的 6个 "字段"的 可取值/字段值 , 这些字段值 除了基本的数字之外还有一些特殊字符。特殊字符的具体说明及示例如下表所示 :
特殊字符 说明 示例 , 表示 枚举。 @Scheduled(cron=" 1,3,5 * * * * * ") : 表示 任意时间 的 第1、第3、第5秒都会执行。 - 表示 区间。 @Scheduled(cron=“0 0-5 14 * * ?”) : 表示每天下午2:00-2:05期间 , 每一分钟执行一次。 * 表示 任意可取值。 @Scheduled(cron=“0 0 12 * * ?”) : 表示每天中午12点触发一次。 / 表示 步长。 @Scheduled(cron=“0/5 * * * * *”) : 表示任意时间的"整秒"开始,每隔5秒都会执行。 ? 日/星期 冲突匹配符。 @Scheduled(cron=“0 * * 26 * ?”) : 表示每月的26日的每一个分钟都执行。 L 表示 最后。 @Scheduled(cron = “0 0 * L * ?”) : 表示每月的最后一日的每一小时都执行。 需要注意的是,注解@Scheduled 的 cron属性 与 cron 的表达式 并 不完全一致,@Scheduled注解 的 cron 属性 只提供 “6位字段” 赋值。cron 表达式 支持的 特殊字符 在 @Scheduled注解 的 cron 属性中是不支持的,例如,字符 C、W、#可以作为 cron 表达式的字符,但是无法作为@Scheduled 的 cron 属性值。
② zone 属性 ( 设置解析"cron属性值"的时区 , 默认以"服务器所在区域"的"本地时区"来解析 “cron属性值” )
- zone属性主要 与 cron 属性 "配合使用",指定 “解析cron 属性值” 的 时区。通常情况下,不需要指定 zone 属性,cron 属性值会自动以 服务器所在区域作为本地时区进行表达式解析。例如,中国地区服务器的 时区 通常 默认 为 Asia/Shanghai。
③ fixedDelay 属性 和 fixedDelayString 属性 ( 在上一次任务"执行完毕后" ,一旦达到执行时间 就 "继续执行"下一次任务 )
fixedDelay 属性 和 fixedDelayString 属性 的 作用类似,用于在上一次任务执行完毕后,一旦到达指定时间 就 继续执行下一次任务。两者的 区别在于属性值的类型不同,fixedDelay属性值 为 long类型 ,而 fixedDelayString属性值 是 数值字符串。例代码如下 :
/* fixedDelay属性 : 用于在上一次任务执行完之后,一旦达到指定时间,就继续执行下一次任务 @Scheduled(fixedDelay = 5000) : 表示程序启动后会立即执行一次定时任务,在任务执行结束后,相隔5秒 (5000毫秒)重复执行定时任务 */ @Scheduled(fixedDelay = 5000) //fixedDelay属性值为 : long类型 。 fixedDelay = 5000 : 表示5秒之后执行下一次任务
/* fixedDelayString属性 : 用于在上一次任务执行完之后,一旦达到指定时间,就继续执行下一次任务 @Scheduled(fixedDelayString = "5000") : 表示程序启动后会立即执行一次定时任务,在任务执行结束后,相隔5秒 (5000毫秒)重复执行定时任务 */ @Scheduled(fixedDelayString = "5000") //fixedDelayString属性值为 : 数值字符串 。 (fixedDelayString = "5000" : 表示5秒之后执行下一次任务
上述代码中,fixedDelay = 5000 和 fixedDelayString = “5000” 都表示程序启动后会立即执行一次定时任务,在任务执行结束后,相隔5秒 (5000毫秒) 重复执行定时任务。
④ fixedRate 属性 和 fixedRateString 属性 ( 每隔一段时间,“重复执行"一次"定时任务” )
fixedRate属性 和 fixedRateString 属性的作用类似,指定 每相隔一段时间, "重复执行" 一次定时任务。它们的 主要区别 : 是 属性值的类型不同,其中 fixedRate属性值 为 long类型 ,fixedRateString 属性值 为 数值字符串。例代码如下 :
/** * fixedRate属性: 表示每隔一段时间重复执行一次定时任务。 * fixedRate = 5000 : 表示在程序启动后立即执行一次定时任务,然后相隔5秒 (5000毫秒) 重复执行定时任务。 */ @Scheduled(fixedRate = 5000) public void scheduledTaskCorn9() { }
/** * fixedRate属性: 表示每隔一段时间重复执行一次定时任务。 * fixedRateString = "5000" : 表示在程序启动后立即执行一次定时任务,然后相隔5秒 (5000毫秒) 重复执行定时任务。 */ @Scheduled(fixedRateString = "5000") public void scheduledTaskCorn10() { }
需要说明的是,fixedRate / fixedRateString 属性与 fixedDelay / fixedDelayString 属性的 作用有些类似,都是 相隔一段时间 “再重复执行” 定时任务。它们 主要区别是: fixedDelay / fixedDelayString 属性的下一次执行时间必须是在上一次任务 "执行完成"后 “开始计时” ;fixedRate / fixedRateString 属性的下一次执行时间是在上一次任务 “执行开始” 时 “开始计时”,如果遇到配置 相隔时间 “小于” 定时任务执行时间,那么 下一次任务会在上一次任务执行完成后 “立即重复执行”。
⑤ initialDelay 属性 和 initialDelayString 属性 ( 指定 “定时任务” “第一次执行” 之前的 “延迟时间” )
initialDelay 属性 和 initialDelayString 属性的 作用类似,主要是与 fixedRate / fixedRateString 或者 fixedDelay / fixedDelayString 属性 配合使用,指定 定时任务 “第一次执行” 的 延迟时间 ( 指定 “定时任务” “第一次执行” 之前的 “延迟时间” ),然后再按照 各自相隔时间重复执行任务 ( "延迟时间"过了,则原本"定时任务"怎么执行就怎么执行 )。示例代码如下 :
//initialDelay : 初始化延迟: 第一次执行任务之前的延迟 @Scheduled(initialDelay = 1000,fixedRate = 5000) //表示程序启动后,会延迟1秒(1000毫秒)后再执行"第一次定时任务",然后相隔5秒(5000毫秒)重复执行"定时任务" public void scheduledTaskCorn11() { }
@Scheduled(initialDelay = 1000,fixedRate = 5000) //表示程序启动后,会延迟1秒(1000毫秒)后再执行"第一次定时任务",然后相隔5秒(5000毫秒)重复执行"定时任务" public void scheduledTaskCorn12() { }
上述代码在程序启动后,会延迟1秒(1000毫秒)后再执行"第一次定时任务" ,然后相隔5秒(5000毫秒) 重复执行"定时任务"。
二、“定时任务” - 案例实现 :
- 下面我们使用 Spring Boot 框架 实现一个简单 的 定时任务。
(1) 创建项目
创建项目 :
需要说明的是,Spring 框架 提供了对 “定时任务” 的支持,SpringBoot框架继承了这一 定时任务 功能。在 Spring Boot 中整合异步任务时,只需在项目中引入Web 模块中的 Web 依赖就可以使用这种定时任务功能。
(2) 编写 “定时任务方法” ( 使用 @Scheduled 注解 )
在项目中创建 service包,并在该包下创建一个 定时任务管理的 业务处理类 ,并在 该类中编写对应的定时任务 处理方法。
ScheduledTaskService.java :
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.Date; @Service //加入IOC容器中 public class ScheduledTaskService { //该类为"业务层中类",用于处理关于"定时任务"的业务 /* 创建 SimpleDateFormat ("简单日期格式"对象) , 用该对象中的.format()方法 来将 "Date对象"( long类型的"时间信息" )转换为 "指定格式" 的 String类型的 "日期信息" */ private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //括号中的参数为: 指定.format()方法输出的"字符串"的"日期格式" private Integer count1 = 1; private Integer count2 = 1; private Integer count3 = 1; //每隔一分钟重复执行一次任务 @Scheduled(fixedRate = 60000) //项目启动后,先立即执行一次任务,然后继续按要求 "继续执行任务" public void scheduledTaskImmediately() { /* String.format() : 该方法用于"格式化字符串"。这个方法接收"一个格式字符串"和 "多个参数",然后根据格式字符串中的指示,将"参数"格式化并"插入"到 "结果字符串"中。 (将参数插入到结果字符串中) */ System.out.println(String.format("fixedRate的第%s次执行, 当前时间为: %s",count1++,dateFormat.format(new Date()))); // 调用.format()方法 输出指定格式的String类型的 "时间信息" } //每隔一分钟重复执行一次任务 (上一次任务执行完之后,等待一分钟再执行该任务) @Scheduled(fixedDelay = 60000) //项目启动后,先立即执行一次任务,然后继续按要求 "继续执行任务" public void scheduledTaskAfterSleep() throws InterruptedException { System.out.println(String.format("fixedDelay的第%s次执行, 当前时间为: %s",count2++,dateFormat.format(new Date()))); Thread.sleep(10000); //休眠10秒 } //每一分钟都执行一次任务 (即每隔一分钟重复执行一次任务 ) @Scheduled(cron = "0 * * * * *") // 因为没具体"秒数"要求,所以项目启动后 ,"整数形式"下才会 "执行任务" public void scheduledTaskAfterCron() throws InterruptedException { System.out.println(String.format("cron的第%s次执行, 当前时间为: %s",count3++,dateFormat.format(new Date()))); } }
(3) "主程序启动类"中 开启基于 “注解” 的"定时任务"支持 ( 使用@EnableScheduling 注解 )
"主程序启动类"中 开启 基于 “注解” 的"定时任务"支持 :
Chapter26Application.java ( 主程序启动类 ) :
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling //开启基于"注解"方式的"定时任务"支持 @SpringBootApplication public class Chapter26Application { public static void main(String[] args) { SpringApplication.run(Chapter26Application.class, args); } }
上面代码中,使用 @Scheduled 注解声明了 3个定时任务方法,这3个方法定制的执行规则基本相同,都是 每隔1分钟重复执行一次定时任务。在使用 fixedDelay 属性的方法 scheduledTaskAfterSleep( )中,使用 Thread.sleep(10000)模拟该定时任务处理耗时为 10 秒。需要说明的是,Spring Boot 使用定时任务相关注解时,必须 先引入Spring框架依赖。
(4) “定时任务” 效果测试
启动项目,此时可在 控制台查看输出效果 :
从上图可以看出,项目启动成功后,配置@Scheduled 注解的 fixedRate 属性 和 fixedDelay 属性 的 定时方法 会 “立即执行” 一次,配置 cron 属性的定时方法会在整数分钟时间点首次执行 ;
接着配置 fixedRate属性 和 cron 属性的方法会每隔1分钟 "重复执行"一次定时任务,而配置 fixedDelav属性的方法是在上一次方法 “执行完成后” “再相隔1分钟后” 才 "重复执行"一次定时任务 。
( 两者逻辑虽然略有不同,但实际的效果是一样的/差不多的 )