在 Spring Framework 中使用 Spring Task 来设置定时任务是一个简单而强大的方式。以下是如何配置和使用 Spring Task 来执行定时任务的详细步骤:
1. 启用 Spring Task
首先,你需要在 Spring 应用中启用任务调度。这可以通过在配置类上添加 @EnableScheduling
注解来实现:
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableScheduling
public class SchedulingConfig {
}
2. 创建定时任务
接着,定义一个包含任务逻辑的方法,并使用 @Scheduled
注解来配置执行的时间表。@Scheduled
注解提供了多种方式来指定任务的执行时间,如固定速率、固定延迟或 cron 表达式:
使用固定速率
每隔一定时间执行一次任务,不论任务执行本身需要多长时间:
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class FixedRateTask {
@Scheduled(fixedRate = 5000) // 每5000毫秒执行一次
public void run() {
System.out.println("Fixed rate task - " + System.currentTimeMillis() / 1000);
}
}
使用固定延迟
任务完成后,等待指定的延迟时间后再次执行:
@Component
public class FixedDelayTask {
@Scheduled(fixedDelay = 5000) // 任务完成后5000毫秒再执行
public void run() {
System.out.println("Fixed delay task - " + System.currentTimeMillis() / 1000);
}
}
使用 Cron 表达式
根据 Cron 表达式定义的时间表来执行任务,更加灵活:
@Component
public class CronTask {
@Scheduled(cron = "0 15 10 * * ?") // 每天上午10:15执行
public void run() {
System.out.println("Cron task - " + System.currentTimeMillis() / 1000);
}
}
3.案例演示
目的:通过定时任务,定时清理阿里云垃圾图片
代码如下:
package com.itheima.task;
import com.itheima.common.constant.RedisConstant;
import com.itheima.common.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Set;
@Component
@Slf4j
public class ImgDelete {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private AliOssUtil aliOssUtil;
@Scheduled(cron = "0 * * * * ?")
public void imgDelete() {
log.info("定时任务开始执行");
//找差集,然后删除差集里面的照片
Set<String> diff = redisTemplate.boundSetOps(RedisConstant.SETMEAL_PIC_RESOURCES).diff(RedisConstant.SETMEAL_PIC_DB_RESOURCES);
for (String s : diff) {
//删除阿里云上的图片,先获取到图片的名字
String imgName = s.substring(s.lastIndexOf("/") + 1);
// 删除图片
aliOssUtil.delete(imgName);
//这是将redis中的多余文件名进行删除
redisTemplate.boundSetOps(RedisConstant.SETMEAL_PIC_RESOURCES).remove(s);
}
}
}
附录:
cron表达式
cron表达式其实就是一个字符串,通过cron表达式可以定义任务触发的时间
构成规则:分为6或7个域,由空格分隔开,每个域代表一个含义每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)
举例:
2022年10月12日上午9点整 对应的cron表达式为:0 0 9 12 10 ? 2022
说明:一般日和周的值不同时设置,其中一个设置,另一个用?表示。
比如:描述2月份的最后一天,最后一天具体是几号呢?可能是28号,也有可能是29号,所以就不能写具体数字。为了描述这些信息,提供一些特殊的字符。这些具体的细节,我们就不用自己去手写,因为这个cron表达式,它其实有在线生成器。
cron表达式在线生成器:在线Cron表达式生成器
可以直接在这个网站上面,只要根据自己的要求去生成corn表达式即可。所以一般就不用自己去编写这个表达式。
通配符:
* 表示所有值;
? 表示未说明的值,即不关心它为何值;
- 表示一个指定的范围;
, 表示附加一个可能值;
/ 符号前表示开始时间,符号后表示每次递增的值;
cron表达式案例:
*/5 * * * * ? 每隔5秒执行一次
0 */1 * * * ? 每隔1分钟执行一次
0 0 5-15 * * ? 每天5-15点整点触发
0 0/3 * * * ? 每三分钟触发一次
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点