导语
在日常的业务开发中,经常会有这样的需求:每天凌晨1点定时备份数据库,定时排查某条数据等业务需求。实现这样的需求就要用到定时任务了。 在SpringBoot中也有对定时任务支持。
- 实现定时任务的步骤
- 启动类上加@EnableScheduling注解
- 编写定时任务要执行的代码,并把任务类和方法交有Spring IOC容器管理
- 了解 cron 表达式
新建一个SpringBoot项目,只需要引入
spring-boot-starter依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
1.在启动类上加上@EnableScheduling注解
@SpringBootApplication
@EnableScheduling
public class SpringBootShedulerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootShedulerApplication.class, args);
}
}
2.编写任务代码
@Component
public class SchedulerOutPutTask {
@Scheduled(cron = "*/5 * * * * ?")
public void schedulerOutPutTask() {
System.out.println(new Date());
}
}
启动运行定时任务就会运行,定时任务代码中的业务根据自己业务需求写在方法中并用@Scheduled(cron="")标识。
3.了解cron表达式
对于定时任务的实现,除业务代码外,最终还是由
cron表达式进行控制执行的周期。
3.1 cron示例
| cron表达式 | 含义 |
|---|---|
| 0 0 10,14,16 * * ? | 每天上午10点,下午2点,4点 |
| 0 0/30 9-17 * * ? | 朝九晚五工作时间内每半小时 |
| 0 0 12 ? * WED | 表示每个星期三中午12点 |
| 0 0 12 * * ? | 每天12点触发 |
| 0 15 10 ? * * | 每天10点15分触发 |
| 0 15 10 * * ? | 每天10点15分触发 |
| 0 15 10 * * ? * | 每天10点15分触发 |
| 0 15 10 * * ? 2005 | 2005年每天10点15分触发 |
| 0 * 14 * * ? | 每天下午的 2点到2点59分每分触发 |
| 0 0/5 14 * * ? | 每天下午的 2点到2点59分(整点开始,每隔5分触发) |
| 0 0/5 14,18 * * ? | 每天下午的 2点到2点59分、18点到18点59分(整点开始,每隔5分触发) |
| 0 0-5 14 * * ? | 每天下午的 2点到2点05分每分触发 |
| 0 10,44 14 ? 3 WED | 3月每周三下午的 2点10分和2点44分触发 |
| 0 15 10 ? * MON-FRI | 从周一到周五每天上午的10点15分触发 |
| 0 15 10 15 * ? | 每月15号上午10点15分触发 |
| 0 15 10 L * ? | 每月最后一天的10点15分触发 |
| 0 15 10 ? * 6L | 每月最后一周的星期五的10点15分触发 |
| 0 15 10 ? * 6L 2002-2005 | 从2002年到2005年每月最后一周的星期五的10点15分触发 |
| 0 15 10 ? * 6#3 | 每月的第三周的星期五开始触发 |
| 0 0 12 1/5 * ? | 每月的第一个中午开始每隔5天触发一次 |
| 0 11 11 11 11 ? | 每年的11月11号 11点11分触发(光棍节) |
| 0 0 1 * * ? | 每天凌晨一点执行一次 |
3.2 cron 表达式格式
cron 表达式分为七个域: 秒 分 时 日 月 周 年 每一个域之间用空格连接,不指定”年“域时,年域可以省略不写: 秒 分 时 日 月 周
3.3 cron表达式七个域列表
| 名称 | 是否必须 | 允许值 | 特殊字符 |
|---|---|---|---|
| 秒 | 是 | 0 - 59 | , - * / |
| 分 | 是 | 0 - 59 | , - * / |
| 时 | 是 | 0 - 23 | , - * / |
| 日 | 是 | 1 - 31 | , - * ? L W C |
| 月 | 是 | 1 - 12 / JAN - DEC | , - * / |
| 周 | 是 | 1 - 7 / SUN - SAT | , - * ? / L C # |
| 年 | 否 | 空 / 1970 - 2099 | , - * / |
注意
需要注意的是“周”域中,使用数值表示时,7表示周六,1表示周日。
3.4 符号的使用
3.4.1 所有域均可用“,”,“-”,“*”,“/”
,x,y表示x和y-x-y表示x到y*表示每TIME/x/y表示从x起,每隔y
3.4.2 “日”域另有“?”,“L”,“W”,“C”
?表示不指定“日”域的值。规则是指定“周”域,则“日”域必须为“?”。反之,指定“日”域,则“周”域必须为“?”。如0 0 12 ? * MON 或 0 0 12 1 * ?L2种写法。一,表示月末几天,如2L, 表示月末的2天。二,表示月末倒数第几天,如L-3,表示月末倒数第3天。W表示临近某日的工作日,如15W,表示最接近15号的工作日,可能是15号(刚好是工作日)、15号前(刚好周六)或15号后(刚好周日)。C表示和Calendar计划关联的值,如1C表示,1日或1日后包括Carlendar的第一天。LWL和W的组合,只能出现在"日"域中。表示某月最后一个工作日,不一定是周五(详细见结尾PS)。
3.4.3 “周”域另有“?”,“L”,“#”,“C”
?表示不指定“周”域。规则是指定“日”域值,则“周”域值必须为“?”。反之,指定“周”域值,则“日”域值必须为“?”。如0 0 12 1 * ? 或 0 0 12 ? * MONL表示某月的最后一个周几,如1L, 表示某月的最后一个周日(1表示周日),7L,表示某月的最后一个周六(7表示周六)。#只能出现在"周"域中,表示第几个周几,x#y,y表示第几个,x表示周的值,如6#2,表示第2个周五(6表示周五)。C表示和Calendar计划关联的值,如1C表示,周日或周日后包括Carlendar的第一天。
注意
“日域”域中,L和W组合为“LW”时,网上有很多种定义,比如: 说法一:LW表示某月的最后一个工作日 说法二:LW某月最后一周的最后一个工作日,即周五