8.1 定时任务
定时任务即系统在特定时间执行一段代码,它的场景应用非常广泛:
购买游戏的月卡会员后,系统每天给会员发放游戏资源。
管理系统定时生成报表。
定时清理系统垃圾。
定时任务的实现主要有以下几种方式:
- Java自带的java.util.Timer类,这个类允许调度一个java.util.TimerTask任务。使用这种方式可以让程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
- Quartz。这是一个功能比较强大的的调度器,可以让程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂。
- Spring3.0以后自带Spring Task,可以将它看成一个轻量级的Quartz,使用起来比Quartz简单许多,在课程中我们使用Spring Task实现定时任务
8.2 SpringTask_Cron表达式
SpringTask依靠Cron表达式配置定时规则。Cron表达式是一个字符串,分成六个或七个域,有以下两种语法格式:
1.Seconds Minutes Hours DayofMonth Month DayofWeek Year
2.Seconds Minutes Hours DayofMonth Month DayofWeek
Seconds(秒):域中可出现,-*/四个字符,以及0-59的整数
*:表示匹配该域的任意值,在Seconds域使用*,表示每秒钟都会触发
,:表示列出枚举值。在Seconds域使用5,20,表示在5秒和20秒各触发一次。
-:表示范围。在Seconds域使用5-20,表示从5秒到20秒每秒触发一次
/:表示起始时间开始触发,然后每隔固定时间触发一次。在Seconds域使用5/20, 表示5秒触发一次,25秒,45秒分别触发一次。
Minutes(分):域中可出现,-*/四个字符,以及0-59的整数
Hours(时):域中可出现,-*/四个字符,以及0-23的整数
DayofMonth(日期):域中可出现,-*/?LWC八个字符,以及1-31的整数
C:表示和当前日期相关联。在DayofMonth域使用5C,表示在5日后的那一天触发,且每月的那天都会触发。比如当前是10号,那么每月15号都会触发。
L:表示最后,在DayofMonth域使用L,表示每个月的最后一天触发
W:表示工作日,在DayofMonth域用15W,表示最接近这个月第15天的工作日触发,如果15号是周六,则在14号即周五触发;如果15号是周日,则在16号即周一触发;如果15号是周二则在当天触发。
注:
- 该用法只会在当前月计算,不会到下月触发。比如在DayofMonth域用
31W,31号是周日,那么会在29号触发而不是下月1号。 - 在DayofMonth域用
LW,表示这个月的最后一个工作日触发。
- 该用法只会在当前月计算,不会到下月触发。比如在DayofMonth域用
Month(月份):域中可出现,-*/四个字符,以及1-12的整数或JAN-DEC的单词缩写
DayofWeek(星期):可出现,-*/?L#C八个字符,以及1-7的整数或SUN-SAT 单词缩写,1代表星期天,7代表星期六
C:在DayofWeek域使用2C,表示在2天后的那一天触发,且每周的那天都会触发。比如当前是周一,那么每周三都会触发。
L:在DayofWeek域使用L,表示在一周的最后一天即星期六触发。在DayofWeek域使用5L,表示在一个月的最后一个星期四触发。
#:用来指定具体的周数,#前面代表星期几,#后面代表一个月的第几周,比如5#3表示一个月第三周的星期四。
?:在无法确定是具体哪一天时使用,用于DayofMonth和DayofWeek域。一般定义了其中一个域,另一个域是不确定的,比如每月20日触发,无法确定20日是星期几,写法如下:0 0 0 20 * ?;或者在每周一触发,此时无法确定该日期是几号,写法如下:0 0 0 ? * 2
Year(年份):域中可出现,-*/四个字符,以及1970~2099的整数。该域可以省略,表示每年都触发。
8.3 注解实现
1.在配置类上添加@EnableScheduling注解
2.在方法上方添加@Scheduled,指定该方法定时执行
// 定时任务类 @Component public class MySpringTask2 { // 打印时间 @Scheduled(cron = "* * * * * *") public void printTime(){ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); String now = sdf.format(new Date()); System.out.println(now+"定时任务2"); } }