本文主要是介绍SpringBoot @Scheduled Cron表达式使用方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《SpringBoot@ScheduledCron表达式使用方式》:本文主要介绍SpringBoot@ScheduledCron表达式使用方式,具有很好的参考价值,希望对大家有所帮助,如有...
Cron 表达式详解
Cron 表达式是用于定义定时任务执行时间的字符串,广泛应用于 Spring 的 @Scheduled、Quartz 等定时任务框架。
其核心是通过 时间字段 和 通配符 组合实现复杂的调度规则。
1. 表达式格式
Cron 表达式由 6或7个字段 组成,分别表示不同时间单位(Spring 中通常用 6位 格式)。
格式如下:
字段 | 允许值 | 特殊字符 | 说明 |
---|---|---|---|
秒(Seconds) | 0-59 | , - * / | 可精确到秒级调度 |
分(Minutes) | 0-59 | , - * / | |
小时(Hours) | 0-23 | , - * / | |
日(Day) | 1-31 | , - * / ? L W | 月份中的某一天 |
月(Month) | 1-12 或 JAN-DEC | , - * / | |
周(Week) | 0-7 或 SUN-SAT (0=周日) | , - * / ? L # | 周几(1=MON, 7=SUN) |
年(Year) | 1970-2099 (可选) | , - * / | Spring 中通常省略 |
2. 特殊字符解析
符号 | 作用 | 示例 |
---|---|---|
* | 匹配任意值 | 0 * * * * ? 每分钟的0秒执行 |
? | 仅在 日 或 周&zwnjjs; 字段使用,表示“无意义” | 0 0 0 * * ? 每天0点执行 |
- | 范围区间 | 0 0 10-12 * * ? 10-12点每小时执行 |
, | 多个值 | 0 0 2,14 * * ? 每天2点和14点执行 |
/ | 步长(间隔时间) | 0 0/5 * * * ? 每隔5分钟执行 |
L | 最后一天(仅 日 或 周 字段) | 0 0 L * * ? 每月最后一天0点执行 |
W | 最近工作日(仅 日 字段) | 0 0 0 15W * ? 每月15日最近的工作日执行 |
# | 指定月份的周几(仅 周 字段) | 0 0 0 ? * 6#3 每月第3个周五执行 |
3. 常用示例
表达式 | 说明 |
---|---|
0 0 12 * * ? | 每天中午12点执行 |
0 0/5 14 * * ? | 每天下午2点开始,每隔5分钟执行一次 |
0 15 10 ? * MON-FRI | 每周一至周五上午10:15执行 |
0 0 0 1 1 ? 2024 | 2024年1月1日0点执行(需7位表达式) |
0 0 8-18/2 ? * MON | 每周一上午8点到下午6点,每隔2小时执行一次 |
0 0 0 L * ? | 每月最后一天的0点执行 |
0 0 0 15W * ? | 每月15日最近的工作日执行 |
0 0 0 ? * 6#3 | 每月第3个周五0点执行 |
4. 重点规则
1. 日与周的互斥性
- 若同时指定 日 和 周,需用 ? 忽略其中一个字段。
- ✅ 正确:0 0 0 ? * MON(每周一执行,忽略日)
- ❌ 错误:0 0 0 * * MON(日和周同时生效,可能冲突)
2. 月份和星期的缩写
- 月份:JAN, FEB, MAR… DEC
- 星期:SUN, MON, TUE… SAT
- L 和 W 的组合
- LW 表示当月的最后一个工作日。
- L-3 表示倒数第3天。
- 年份字段(可选)
- Spring 的 @ScheduChina编程led 不支持年份字段,需用6位表达式。
5. 动态与复杂场景
1. 动态 Cron 表达式
- Spring 中可通过 @Scheduled(cron = “${cron.expression}”) 从配置文件读取。
- 结合数据库动态更新任务:
@Scheduled(cron = "#{@cronService.getCronExpression()}") public void dynamicTask() { // 业务逻辑 }
2. 避开整点任务高峰
- 添加随机延迟(避免多个任务同时触发):
@Scheduled(cron = "0 #{T(Java.util.concurrent.ThreadLocalRandom).current().nextInt(55)} * * * ?") public void randomMinuteTask() { // 每小时随机分钟执行 }
3. 闰年处理
- Cron 无法直接处理闰年,需结合代码逻辑判断。
6. 调试与验证
www.chinasem.cn1. 在线工具
- Crontab Guru:快速验证表达式。
- CronMaker:生成表达式并查看下次执行时间。
- 日志调试
- 在任务方法中添加日志,观察触发时间是否符合预期:
@Scheduled(cron = "0 0/5 * * * ?") public void loChina编程gTask() { log.info("任务执行时间: {}", LocalDateTime.now()); }
7. 常见问题
1. 为什么任务没有执行?
- 检查是否添加
@EnableScheduling
。 - 检查 Cron 表达式是否正确(如 Spring 不支持年份字段)。
- 检查时区设置(默认使用服务器时区,可通过 zone 属性修改)。
2. 如何实现每隔 N 天执行?
方案1
:使用0 0 0 */N * ?
(如0 0 0 */5 * ?
每隔5天执行)。方案2
:通过代码记录上一次执行时间。
3. 分布式环境下的幂等性
使用 Redis 分布式锁:
@Scheduled(cron = "0 0 * * * ?") public void distributedTask() { if (redisLock.tryLock("taskLock", 10)) { try { // 业务逻辑 } finally { redisLock.unlock("taskLock"); } } }
总结
Cron China编程表达式通过简洁的语法实现了灵活的定时规则,但需注意 字段互斥性 和 特殊字符的适用场景。
在复杂业务中,可结合动态配置、分布式锁和日志监控来确保任务稳定执行。
这篇关于SpringBoot @Scheduled Cron表达式使用方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!