Spring Task 提供輕量級定時調度,@Scheduled 支援固定延遲、固定頻率、Cron 表達式三種模式。本文詳解配置、用法、Cron 參數表、不支援年份字段的關鍵避坑。
<beans xmlns:task="https://www.springframework.org/schema/task" ...>
<task:executor id="executor" pool-size="10" queue-capacity="128"/>
<task:scheduler id="scheduler" pool-size="10"/>
<task:annotation-driven executor="executor" scheduler="scheduler" proxy-target-class="true"/>
</beans>
或 Java Config:@EnableScheduling + 自定義 TaskScheduler Bean。
| 模式 | 屬性 | 含義 | 示例 |
|---|---|---|---|
| 固定延遲 | fixedDelay | 上一次執行結束 → 間隔 N 毫秒 → 下一次開始 | @Scheduled(fixedDelay = 5000) |
| 固定頻率 | fixedRate | 上一次執行開始 → 間隔 N 毫秒 → 下一次開始 | @Scheduled(fixedRate = 5000) |
| Cron 表達式 | cron | 複雜時間規則(秒 分 時 日 月 周) | @Scheduled(cron = "0 0 2 * * ?") |
秒(0-59) 分(0-59) 時(0-23) 日(1-31) 月(1-12) 周(1-7 或 SUN-SAT)
| 特殊符號 | 含義 | 示例 |
|---|---|---|
| * | 所有值 | * * * * * * 每秒 |
| ? | 不指定值(日/周互斥) | 0 0 12 ? * * 每天中午 |
| - | 範圍 | 9-17 9點到17點 |
| , | 列表 | MON,WED,FRI |
| / | 增量 | 0/15 每15分鐘 |
| L | 最後 | 日:L 月最後一天,周:L 週六 |
| W | 工作日 | 15W 最近工作日 |
| # | 第 N 個周X | 6#3 第3個週五 |
0 0 12 * * ? 每天中午 12:00
0 15 10 ? * MON-FRI 工作日 10:15
0 0 12 ? * 6L 每月最後週六 12:00
0 15 10 ? * 6#3 每月第3個週五 10:15
0 0/5 14 * * ? 14:00-14:55 每5分鐘
0 0/5 14,18 * * ? 14點和18點各每5分鐘
Quartz Cron 支援 7 字段(含年),但 Spring CronSequenceGenerator 解析器強制要求 6 字段。
// 錯誤:7 字段會拋 IllegalStateException
@Scheduled(cron = "0 18 10 * * ? 2016-2016")
// 正確:6 字段
@Scheduled(cron = "0 18 10 * * ?")
源碼驗證:
String[] fields = StringUtils.tokenizeToStringArray(expression, " ");
if (fields.length != 6) throw new IllegalArgumentException(
"cron expression must consist of 6 fields (found " + fields.length + " in \"" + expression + "\")");
return。Spring Quartz Scheduler。@Async + 自定義執行器),避免佔用調度線程。