搶先一步
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 通常傾向於保持向後相容性,但有時我們確實認為從頭開始是最佳選擇。
您通常使用 @Scheduled
註解建立 cron 觸發器,從 Spring Framework 5.3 開始,它在內部使用 CronExpression
。這表示如果您使用的是該版本,就可以開始使用新功能。
如果您想親自試用 CronExpression
,可以透過靜態的 parse 方法建立一個
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 是星期日) │ │ │ │ │ │ * * * * * *
適用一些規則
欄位可以是星號 (*
),它始終代表「first-last」。對於月份中的日期或星期幾欄位,可以使用問號 (?
) 來代替星號。
逗號 (,
) 用於分隔列表中的項目。
用連字號 (-
) 分隔的兩個數字表示數字範圍。指定的範圍是包含在內的。
在範圍(或 *
)後加上 /
指定數字的值在範圍內的間隔。
英文名稱也可以用於月份中的日期和星期幾欄位。使用特定日期或月份的前三個字母(大小寫不拘)。
以下是一些範例
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 * * * *
之類的表達式對於人類來說很難解析,因此,如果出現錯誤,也很難修復。為了提高可讀性,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 版本的一部分。