Hello,大家好,我是Yize,在进行学习时遇到了SpringTask ,因为感觉挺有趣,而且很实用,索性就去了解了一点,下面就跟我一起来学习吧!!
目录
[一、什么是 Spring Task?](#一、什么是 Spring Task?)
[1. 固定延迟(fixedDelay)](#1. 固定延迟(fixedDelay))
[2. 固定速率(fixedRate)](#2. 固定速率(fixedRate))
[3. Cron 表达式(最常用 ⭐)](#3. Cron 表达式(最常用 ⭐))
[四、Cron 表达式详解(重点!)](#四、Cron 表达式详解(重点!))
[🔥 常见 Cron 示例速查表](#🔥 常见 Cron 示例速查表)
[六、苍穹外卖中的实际应用场景 🍔](#六、苍穹外卖中的实际应用场景 🍔)
[七、注意事项 ⚠️](#七、注意事项 ⚠️)
[🚀 多线程优化(进阶)](#🚀 多线程优化(进阶))
一、什么是 Spring Task?
Spring Task 是 Spring 框架提供的定时任务解决方案,允许你在指定的时间自动执行某些代码逻辑,无需额外引入第三方框架(如 Quartz)。
核心思想:通过注解配置,让某个方法在指定时间自动执行。
二、核心注解
| 注解 | 作用 | 说明 |
|---|---|---|
@EnableScheduling |
开启定时任务支持 | 加在启动类 或配置类上 |
@Scheduled |
标记定时执行的方法 | 加在方法上 |
三、三种配置方式
1. 固定延迟(fixedDelay)
上一次执行完成后,间隔指定时间再执行。
@Scheduled(fixedDelay = 5000) // 上次任务结束后,等5秒再执行
public void task1() {
System.out.println("fixedDelay 执行:" + LocalDateTime.now());
}
⏱️ 场景:适合任务执行时间不确定,需要"做完一个再等一会儿做下一个"的情况。
2. 固定速率(fixedRate)
每隔指定时间执行一次,不管上次是否执行完。
@Scheduled(fixedRate = 3000) // 每3秒执行一次
public void task2() {
System.out.println("fixedRate 执行:" + LocalDateTime.now());
}
⏱️ 场景:适合任务执行时间稳定、需要严格按频率执行的场景。
3. Cron 表达式(最常用 ⭐)
通过 Cron 表达式灵活控制执行时间。
@Scheduled(cron = "0 0 12 * * ?") // 每天中午12点执行
public void task3() {
System.out.println("Cron 执行:" + LocalDateTime.now());
}
四、Cron 表达式详解(重点!)
Cron 表达式由 6~7 个字段 组成:
秒 分 时 日 月 周 年(可选)
* * * * * * ?
| 字段 | 含义 | 取值范围 |
|---|---|---|
| 秒 | Seconds | 0-59 |
| 分 | Minutes | 0-59 |
| 时 | Hours | 0-23 |
| 日 | Day of Month | 1-31 |
| 月 | Month | 1-12 |
| 周 | Day of Week | 1-7(1=周日)或 MON-SUN |
| 年 | Year(可选) | 留空即可 |
常用通配符
| 符号 | 含义 | 示例 |
|---|---|---|
* |
所有值 | * 表示每秒/每分/每小时 |
? |
不指定(日和周互斥时用) | ? 用在日或周字段 |
- |
范围 | 10-12 → 10、11、12 |
, |
枚举多个值 | 1,3,5 → 1、3、5 |
/ |
步长(每隔) | 0/5 → 每5个单位 |
L |
最后 | L 表示最后一天 |
W |
最近工作日 | 15W → 15号最近的工作日 |
🔥 常见 Cron 示例速查表
| 表达式 | 含义 |
|---|---|
0 0 0 * * ? |
每天凌晨0点 |
0 30 8 * * ? |
每天早上8:30 |
0 0 12 * * ? |
每天中午12:00 |
0 0 0 ? * MON |
每周一凌晨0点 |
0 0 0 1 * ? |
每月1号凌晨0点 |
0 0 0 1 1 ? |
每年1月1日0点 |
0 */5 * * * ? |
每5分钟执行一次 |
0 0 8-18 * * ? |
每天8点到18点整点执行 |
0 0 0 L * ? |
每月最后一天0点 |
0 0 0 ? * 6L |
每月最后一个周五0点 |
💡 记忆口诀 :日和周只能指定一个,另一个用
?占位。💡 Cron 表达式在线生成器: https://cron.ciding.cc/
五、完整代码示例
第一步:启动类加注解
@SpringBootApplication
@EnableScheduling // ← 开启定时任务
public class SkyApplication {
public static void main(String[] args) {
SpringApplication.run(SkyApplication.class, args);
}
}
第二步:编写定时任务类
@Component
@Slf4j
public class MyTask {
/**
* 每5秒执行一次(固定速率)
*/
@Scheduled(fixedRate = 5000)
public void fixedRateTask() {
log.info("fixedRate 任务执行:{}", LocalDateTime.now());
}
/**
* 每天凌晨1点执行(Cron)
*/
@Scheduled(cron = "0 0 1 * * ?")
public void dailyTask() {
log.info("每日定时任务执行");
// 实际业务:清理过期数据、生成报表等
}
/**
* 每10秒执行一次(固定延迟)
*/
@Scheduled(fixedDelay = 10000)
public void fixedDelayTask() {
log.info("fixedDelay 任务执行:{}", LocalDateTime.now());
}
}
六、苍穹外卖中的实际应用场景 🍔
结合项目,Spring Task 的典型用法:
场景1:定时清理过期订单
/**
* 每分钟检查一次,自动取消超时未支付的订单
*/
@Scheduled(cron = "0 0/1 * * * ?") // 每1分钟执行
public void cancelTimeoutOrders() {
// 查询超过15分钟未支付的订单
// 将其状态改为「已取消」
log.info("自动取消超时订单...");
}
场景2:定时处理「已完成」的订单
/**
* 每天凌晨2点,将前一天已完成的订单做数据统计
*/
@Scheduled(cron = "0 0 2 * * ?")
public void processCompletedOrders() {
// 统计营业额、清理临时数据等
log.info("处理已完成订单数据...");
}
场景3:定时推送营业提醒
/**
* 每天早上9点推送营业提醒
*/
@Scheduled(cron = "0 0 9 * * ?")
public void sendOpenReminder() {
// 推送消息给商家
log.info("发送营业提醒...");
}
七、注意事项 ⚠️
| 要点 | 说明 |
|---|---|
| 单线程执行 | 默认所有 @Scheduled 任务共用一个线程,任务多了会排队 |
| 方法必须是 void | @Scheduled 注解的方法不能有返回值 |
| 方法不能有参数 | 定时任务方法不支持传参 |
| 类需被 Spring 管理 | 任务类要加 @Component 等注解 |
| 分布式慎用 | 单机没问题,集群部署时需要配合 Redis 分布式锁 或 XXL-Job |
🚀 多线程优化(进阶)
如果任务多了需要并行执行,可以配置线程池:
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setTaskScheduler(taskScheduler());
}
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5); // 5个线程
scheduler.setThreadNamePrefix("scheduled-task-");
return scheduler;
}
}
八、总结脑图
Spring Task
├── 核心注解
│ ├── @EnableScheduling(开启)
│ └── @Scheduled(标记方法)
├── 三种方式
│ ├── fixedDelay → 上次结束后间隔
│ ├── fixedRate → 固定频率
│ └── cron → 灵活时间(最常用)
├── Cron 表达式
│ ├── 6个字段:秒 分 时 日 月 周
│ └── 通配符:* ? - , / L W
└── 注意事项
├── 默认单线程
├── 方法无参无返回值
└── 集群需配合分布式锁
好啦!本期的学习到此结束,我们下期再见!!!