Spring 定時任務 @Scheduled 的使用

1. 定時任務的使用

1.1 使用示例

  1. 在啓動類上添加 @EnableScheduling註解

    @SpringBootApplication
    @EnableAsync
    @EnableScheduling
    public class Application {
       public static void main(String[] args) {
           SpringApplication.run(Application.class, args);
       }
    }
    
  2. 創建任務類,在需要定時執行的方法上面添加註解@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 常見例子

Cron在線工具

0 15 10 ? 6L 2002-2006 表示2002-2006年的每個月的最後一個星期五上午10:15執行作業
0 0 10,14,16 * * ?   每天上午10點,下午2點,40 0/30 9-17 * * ?   朝九晚五工作時間內每半小時 
0 15 10 ? * 6#3   每月的第三個星期五上午10:15觸發
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章