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 功能强大,支持 */na-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 表达式指南


原始标题:The Difference Between Cron Syntax in Linux and Spring