1. 定時任務的使用
1.1 使用示例
-
在啓動類上添加
@EnableScheduling
註解@SpringBootApplication @EnableAsync @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
-
創建任務類,在需要定時執行的方法上面添加註解
@Scheduled
,並指定執行計劃@Slf4j @Component @Lazy(false) public class CreateTableJob { @Autowired private ActionEventRepository actionEventRepository; /** * 每月 28 號 00:00:00 創建下月的表 */ @Scheduled(cron = "0 0 0 28 1-12 ?") public void createTable() { String tableName = ActionEventTableUtil.getNextMonthTableName(); log.warn("It is time to create next month table:{}", tableName); try { actionEventRepository.createTable(tableName); } catch (Exception e) { log.warn("Cron job create next month table:" + tableName + "fail!", e); } } }
1.2 注意事項
1
.定時執行的方法不能有參數
2
.定時執行的方法不能有返回值
3
.@Scheduled
默認是單線程串行執行,多個定時任務同時執行可能會發生阻塞。此時可在啓動類上添加註解@EnableAsync
,並在定時執行的方法上添加註解@Async
使其異步執行
4
. Spring 打開延時加載策略時會導致定時任務類沒在啓動時加載進任務隊列,無法正確執行。解決方法是在定時任務類上添加註解@Lazy(false)
,指定其關閉延時加載策略
2. Cron 表達式相關
2.1 Cron 表達式格式
Cron
表達式的格式是 [Seconds] [Minutes] [Hours] [DayofMonth] [Month] [DayofWeek] [Year]
字段 | 候選值 | 允許的特殊字符 |
---|---|---|
秒(Seconds) | 0~59的整數 | , - * / |
分(Minutes) | 0~59的整數 | , - * / |
小時(Hours) | 0~23的整數 | , - * / |
日期(DayofMonth) | 1~31的整數(但需考慮各月的天數) | ,- * ? / L W C |
月份(Month) | 1~12的整數或 JAN-DEC |
, - * / |
星期(DayofWeek) | 1~7的整數或者 SUN-SAT (1=SUN) |
, - * ? / L C # |
年(可選,留空)(Year) | 1970~2099 | , - * / |
2.2 特殊字符詳解
特殊符號 | 含義 |
---|---|
* |
代表所有的取值範圍內的數字 |
/ |
代表每的意思,"0/5"表示從0位置開始,每5個單位執行一次 |
- |
代表範圍,比如從某個數字到某個數字 |
, |
分開的幾個枚舉值 |
? |
只能用在 DayofMonth 和 DayofWeek 兩個域,表示不指定值。例如想在每月的20日觸發調度,不管20日到底是星期幾,則只能使用寫法:13 13 15 20 * ? , 其中最後一位只能用? ,而不能使用* ,如果使用* 表示不管星期幾都會觸發,這會產生衝突 |
L |
表示最後,只能出現在 DayofWeek 和 DayofMonth 域。如果在 DayofWeek 域使用5L , 意味着在最後的一個星期四觸發 |
W |
表示有效工作日(週一到週五),只能出現在DayofMonth域,系統將在離指定日期的最近的有效工作日觸發事件。例如:在 DayofMonth使用5W,如果5日是星期六,則將在最近的工作日:星期五,即4日觸發。如果5日是星期天,則在6日(週一)觸發;如果5日在星期一到星期五中的一天,則就在5日觸發。另外一點,W的最近尋找不會跨過月份 |
LW |
這兩個字符可以連用,表示在某個月最後一個工作日,即最後一個星期五。 |
# |
用於確定每個月第幾個星期幾,只能出現在DayofMonth域。例如在4#2,表示某月的第二個星期三 |
2.3 常見例子
0 15 10 ? 6L 2002-2006 表示2002-2006年的每個月的最後一個星期五上午10:15執行作業
0 0 10,14,16 * * ? 每天上午10點,下午2點,4點
0 0/30 9-17 * * ? 朝九晚五工作時間內每半小時
0 15 10 ? * 6#3 每月的第三個星期五上午10:15觸發