前言
在系统中使用定时任务已经是一个比较常见的事情,比如需要定时发送邮件报告,生成系统日志,进行数据归档等。Spring3.0 起加入了任务调度功能 Schedule, 它不需要使用依赖其他 JAR 包,使用起来比较方便。
在 SpringBoot 中使用 scheduled,在项目启动类上添加注解 @EnableScheduling 来开启任务调度,然后在方法上使用注解 @Scheduled
@Scheduled(fixedRate = 5000)
public void fixedRate() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.info("The time is now {}", dateFormat.format(new Date()));
}
@Scheduled(fixedDelay = 5000)
public void fixedDelay() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.info("The time is now {}", dateFormat.format(new Date()));
}
@Scheduled(initialDelay = 5000, fixedDelay = 5000)
public void initialDelay() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.info("The time is now {}", dateFormat.format(new Date()));
}
@Scheduled(cron = "0/10 * * * * *")
public void reportCurrentTime() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.info("The time is now {}", dateFormat.format(new Date()));
}
注意到这里有几个常用的 Scheduled 参数:
- fixedRate:每间隔多长时间调用一次该方法
- fixedDelay: 上一次任务完成后,间隔多长时间调用该方法
- initialDelay:首次任务启动延迟多长时间
- cron: 按照指定的表达式实行更精细的任务调度
Cron 每个域的含义为:{秒} {分} {时} {日} {月} {周},对应的范围如下:
域 | 范围 | 可用的特殊字符 |
---|---|---|
秒 | 0-59 | , - * / |
分 | 0-59 | , - * / |
时 | 0-23 | , - * / |
日 | 1-31 | , - * / ? |
月 | 1-12 或 JAN-DEC | , - * / |
周 | 0-7(0和7都是星期天) 或 SUN-SAT | , - * / ? |
Cron 使用例子
cron 表达式 | 含义 |
---|---|
0 0 * * * * | 每小时执行一次 |
*/10 * * * * * | 每10秒执行一次 |
0 0 8-10 * * * | 每天 8,9,10点执行一次 |
0 0 6,19 * * * | 每天上午6点和下午7点执行一次 |
0 0/30 8-10 * * * | 每天8:00, 8:30, 9:00, 9:30, 10:00, 10:30 执行一次 |
0 0 9-17 * * MON-FRI | 工作日上午9点到下午5点每小时执行一次 |
0 0 0 25 12 ? | 每个圣诞节的午夜触发一次 |
注意上面用到的特殊字符:, - * / ?,它们的含义是:
- ",": 表示枚举多个值
- "-":表示范围
- "*": 匹配该域的任意值
- "/": 表示从起始时间触发一次后每隔多长时间执行一次
- "?": 只能在日和周域使用, 表示不明确的值,作用和 “*” 一样,匹配任意值
创建项目
项目结构图如下:
pom 依赖文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>top.yekongle</groupId>
<artifactId>springboot-scheduled-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-scheduled-sample</name>
<description>Scheduled project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
代码编写
SpringbootScheduledSampleApplication.java, 项目启动类
package top.yekongle.scheduled;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @EnableScheduling 开启任务调度
* */
@SpringBootApplication
@EnableScheduling
public class SpringbootScheduledSampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootScheduledSampleApplication.class, args);
}
}
ScheduledJob.java, 任务调度类
package top.yekongle.scheduled.job;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class ScheduledJob {
// 时间格式化
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 每5秒执行一次,无论上次任务执行结束与否,参数单位是毫秒
@Scheduled(fixedRate = 5000)
public void fixedRate() {
log.info("fixedRate>>>:{}", format.format(new Date()));
}
// 当上次任务执行结束后,间隔5秒再执行下次任务,参数单位是毫秒
@Scheduled(fixedDelay = 5000)
public void fixedDelay() {
log.info("fixedDelay>>>:{}", format.format(new Date()));
}
// initialDelay 表示首次任务启动的延迟时间,参数单位是毫秒
@Scheduled(initialDelay = 5000, fixedDelay = 5000)
public void initialDelay() {
log.info("initialDelay>>>:{}", format.format(new Date()));
}
// 使用cron表达式,可以按照cron的逻辑执行代码, 实行更精细的任务调度
// 每隔10秒执行一次
@Scheduled(cron = "0/10 * * * * *")
public void startJob() {
log.info("Cron job:{}", format.format(new Date()));
}
}
运行测试
项目已上传至 Github: https://github.com/yekongle/springboot-code-samples/tree/master/springboot-scheduled-sample , 希望对小伙伴们有帮助哦。