領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多如果您經常收聽 A Bootiful Podcast,您可能已經聽說過我們對 Spring Framework 的 cron 支援所做的改進。Cron 表示式主要透過 @Scheduled 註解在 Spring 應用程式中使用。在 Spring 5.3 中,我們引入了 CronExpression 類,它代表——您猜對了——一個 cron 表示式。
CronExpression 替代了 CronSequenceGenerator,後者基於 java.util.Calendar 並且存在一些已知問題,Spring 團隊成員都不太願意解決這些問題。引入新型別使我們能夠使用更優越的 java.time API,解決現有問題,並(希望能)引入新功能。雖然 Spring 通常傾向於保持向後相容,但有時我們確實認為從頭開始是最佳選擇。
從 Spring Framework 5.3 開始,你通常使用 @Scheduled 註解建立 cron 觸發器,該註解內部使用 CronExpression。這意味著如果你使用的是該版本,你已經可以開始使用新功能。
如果你想自己使用 CronExpression,可以透過靜態解析方法建立一個
var expression = CronExpression.parse("10 * * * * *");
var result = expression.next(LocalDateTime.now());
System.out.println(result);
在此示例中,expression 表示一個 cron 序列,它在每分鐘的第 10 秒觸發。parse 方法接受帶有六個空格分隔的時間和日期欄位的眾所周知的字串
┌───────────── 秒 (0-59) │ ┌───────────── 分鐘 (0 - 59) │ │ ┌───────────── 小時 (0 - 23) │ │ │ ┌───────────── 月份中的日期 (1 - 31) │ │ │ │ ┌───────────── 月份 (1 - 12) (或 JAN-DEC) │ │ │ │ │ ┌───────────── 星期幾 (0 - 7) │ │ │ │ │ │ (或 MON-SUN -- 0 或 7 是星期日) │ │ │ │ │ │ * * * * * *
適用一些規則
欄位可以是星號 (*),它始終表示“從頭到尾”。對於月份中的日期或星期幾欄位,可以使用問號 (?) 代替星號。
逗號 (,) 用於分隔列表項。
兩個數字用連字元 (-) 分隔表示一個數字範圍。指定的範圍是包含的。
在範圍(或 *)後跟 / 指定數字值在範圍內的間隔。
月份中的日期和星期幾欄位也可以使用英文名稱。使用特定日期或月份的前三個字母(不區分大小寫)。
以下是一些示例
Cron 表示式
含義
0 0 * * * *
每天每小時的整點
*/10 * * * * *
每十秒
0 0 8-10 * * *
每天的 8、9 和 10 點
0 0 6,19 * * *
每天早上 6:00 和晚上 7:00
0 0/30 8-10 * * *
每天的 8:00、8:30、9:00、9:30、10:00 和 10:30
0 0 9-17 * * MON-FRI
工作日九點到五點每小時的整點
0 0 0 25 12 ?
每年聖誕節午夜
next 方法返回觸發器的下一次出現,如果沒有則返回 null。它以 java.time.temporal.Temporal 作為引數,這意味著它不僅接受 LocalDateTime,如果時區相關,還接受 ZonedDateTime。
使用 java.time API 使我們能夠引入一些新功能,使 Spring 對 cron 表示式的支援與其他排程器處於同等地位。從 Spring Framework 5.3 開始,你可以在 @Scheduled 中開始使用這些功能。
像 0 0 * * * * 這樣的表示式對人類來說很難解析,因此在出現 bug 時很難修復。為了提高可讀性,Spring 現在支援以下宏,它們代表常用的序列。你可以使用這些宏代替六位數值,例如:@Scheduled(cron = "@hourly")。
宏
含義
@yearly (或 @annually)
每年一次 (0 0 0 1 1 *)
@monthly
每月一次 (0 0 0 1 * *)
@weekly
每週一次 (0 0 0 * * 0)
@daily (或 @midnight)
每天一次 (0 0 0 * * *),或
@hourly
每小時一次 (0 0 * * * *)
月份中的日期和星期幾欄位可以包含一個 L 字元,它在每個欄位中具有不同的含義。在月份中的日期欄位中,L 表示該月的最後一天。如果後跟負偏移量(即 L-n),則表示該月的倒數第 n 天。
在星期幾欄位中,L 表示該周的最後一天。如果字首為數字或三個字母的名稱(dL 或 DDDL),則表示該月中的星期幾(d 或 DDD)的最後一天。
以下是一些示例
Cron 表示式
含義
0 0 0 L * *
每月最後一天的午夜
0 0 0 L-3 * *
每月倒數第三天的午夜
0 0 0 * * 5L
每月最後一個星期五的午夜
0 0 0 * * THUL
每月最後一個星期四的午夜
月份中的日期欄位可以是 nW,它表示離該月第 n 天最近的工作日。如果 n 落在星期六,則表示它之前的星期五。如果 n 落在星期日,則表示它之後的星期一,如果 n 是 1 並且落在星期六(即:1W 表示該月的第一個工作日),也會發生這種情況。
如果月份中的日期欄位是 LW,則表示該月的最後一個工作日。
以下是一些示例
Cron 表示式
含義
0 0 0 1W * *
每月第一個工作日的午夜
0 0 0 LW * *
每月最後一個工作日的午夜
星期幾欄位可以是 d#n (或 DDD#n),它表示該月中的第 n 個星期 d (或 DDD)。
以下是一些示例
Cron 表示式
含義
0 0 0 ? * 5#2
該月第二個星期五的午夜
0 0 0 ? * MON#1
該月第一個星期一的午夜
改進的 cron 表示式支援只是 Spring Framework 5.3 提供的眾多功能之一,並且將成為即將釋出的Spring Boot 2.4 版本的一部分。