1. 概述
Cron 表达式让我们可以按指定的时间周期性地执行任务。自从在 Unix 系统中引入后,这种语法被大多数类 Unix 系统以及各类软件框架(包括 Spring 框架)广泛采用,用于实现任务调度。
本文将清晰地对比 Unix 系统与 Spring 框架中 Cron 表达式的区别,帮你避免在实际开发中“踩坑”。
2. Unix 系统中的 Cron
在大多数 Unix 系统中,Cron 表达式由 5 个字段组成,依次为:
- 分钟(0–59)
- 小时(0–23)
- 日期(1–31)
- 月份(1–12 或英文缩写)
- 星期几(0–7,其中 0 和 7 都代表周日,也支持英文缩写)
✅ 示例:每天凌晨 00:05 执行一次:
5 0 * * *
✅ 支持范围(range):每天从 00:05 到 05:05,每小时执行一次:
5 0-5 * * *
✅ 支持列表(list):每天 00:05 和 03:05 执行:
5 0,3 * * *
Unix Cron 功能强大,支持 */n
、a-b/c
等复杂语法,详细可参考 Cron 表达式指南。
⚠️ 但有一个致命限制:不支持秒级精度,因为它根本没有“秒”这个字段。
这就引出了 Spring 的改进方案。
3. Spring 中的 Cron
在 Spring 中,我们通常使用 @Scheduled
注解配合 Cron 表达式来调度任务:
@Scheduled(cron = "0 0 8 * * ?")
public void dailyTask() {
// 每天早上8点执行
}
与 Unix 不同,Spring 的 Cron 表达式有 6 个字段,顺序如下:
字段位置 | 含义 |
---|---|
1 | 秒(0–59) |
2 | 分(0–59) |
3 | 时(0–23) |
4 | 日(1–31) |
5 | 月(1–12) |
6 | 星期几(1–7,1=周日) |
✅ 每 10 秒执行一次任务:
*/10 * * * * *
✅ 每天 8:00 到 10:59 之间,每 20 秒执行一次:
*/20 * 8-10 * * *
🔍 关键区别:Spring 多了一个“秒”字段,且放在第一位。这是两者最核心的差异。
此外,Spring 的 Cron 还支持一些 Unix 不支持的特性,比如:
- 使用
?
表示“不指定值”(常用于“日”和“星期”字段互斥) - 支持年份字段(可选的第 7 位,但很少用)
底层实现由 Spring 的 CronSequenceGenerator
类负责解析表达式,逻辑严谨,性能也不错。
4. 总结
对比项 | Unix Cron | Spring Cron |
---|---|---|
字段数量 | 5 个 | 6 个(含秒) |
秒级支持 | ❌ 不支持 | ✅ 支持 |
第一个字段 | 分钟 | 秒 |
特殊字符 ? |
❌ 不支持 | ✅ 支持(用于日/星期互斥) |
底层实现 | 系统级 crond | CronSequenceGenerator |
📌 简单粗暴记法:Spring 的 Cron 比 Unix 多一个“秒”字段,且放在最前面。
📌 实际开发中,尤其在微服务定时任务场景下,务必确认使用的是 Spring 的 6 位语法,否则 @Scheduled
会直接报错或行为异常。
建议:
- 多用在线 Cron 表达式测试工具验证逻辑
- 查看
CronSequenceGenerator
源码,理解边界处理逻辑 - 统一团队 Cron 编写规范,避免混淆
如需更多 Cron 示例,推荐阅读我们的 Cron 表达式指南。