spring cron表達式源碼分析

在springboot中,我們一般是通過如下的做法添加一個定時任務

spring cron表達式源碼分析

文章插圖
上面的new CronTrigger("0 * * * * *")中的參數0 * * * * *就是cron表達式了 。
這里主要是對cron表達式的源碼進行分析,其他內容不再展開了 。
這能看到會創建一個CronTrigger對象,這個對象它主要就是用來包裝解析后的cron表達式,獲取任務下次執行的時間 。
spring cron表達式源碼分析

文章插圖
在CronTrigger構造方法中會調用到this.expression = CronExpression.parse(expression);將我們傳入的cron字符串解析成為CronExpression對象 。
CronExpression主要有一個next方法,它會根據當前cron表達式解析出來的對象,以及傳入的時間,返回一個時間值,也就是下次任務執行的時間 。
spring cron表達式源碼分析

文章插圖
這里的入參需要實現Temporal接口 。這是在JDK8引入的一套全新的時間、日期 。
能引入新的,至少說明之前的Date等等之類的時間處理是不能滿足各方面需要的 。
下面看看它的主要實現
spring cron表達式源碼分析

文章插圖
這里我們一般常用的可能就是Instant,LocalDateTime,ZonedDateTime了 。
從上面就可以看到cron表達式的處理,主要是分為兩步:1、將cron表達式字符串解析為CronExpression對象;2、根據傳入的時間計算下次任務的執行時間 。
在分析源碼之前,我們簡單看幾個java中的類
  1. ValueRange主要用來表示時間、日期字段的有效范圍 。當然它也可以不用來表示時間、日期 。下面我們簡單看下它的使用 。
    它主要有4個字段,4個屬性值從上到下是不小于的關系 。
private final long minSmallest;   //最小的最小值private final long minLargest;    //較大的最小值private final long maxSmallest;   //較小的最大值private final long maxLargest;    //最大的最大值//定義1個(1-10)的范圍指定minSmallest和minLargest都是1,maxSmallest和maxLargest都是10ValueRange valueRange=ValueRange.of(1,10);//判斷5是不是在上面定義的minSmallest和maxLargest(1-10)的范圍內,在的話返回trueboolean validValue = valueRange.isValidValue(5);System.out.println(validValue);
  1. ChronoField是一個枚舉類 , 就是用來表示時間、日期的字段 。
    下面我們簡單看它的幾個實例
//用納秒來表示表,1秒==1000000000納秒,所以它的范圍是0-999999999NANO_OF_SECOND("NanoOfSecond", NANOS, SECONDS, ValueRange.of(0, 999_999_999)),//用納秒來表示一天,1天==86400秒,再轉成納秒就是86400L*1000000000NANO_OF_DAY("NanoOfDay", NANOS, DAYS, ValueRange.of(0, 86400L * 1000_000_000L - 1)),......其他基本類似 , 就不繼續說了
  1. ChronoUnit也是一個枚舉類 , 表示一個時間單元 。有一個addTo方法表示給時間加上一個對應的時間單元 。
//下面的代碼就是給當前時間加上1天ZonedDateTime now = ZonedDateTime.now();ZonedDateTime zonedDateTime = ChronoUnit.DAYS.addTo(now, 1);我們先看第一步:
1、將cron表達式字符串解析為CronExpression對象我們傳入的表達式用空格分成6個部分,每個部分代表的含義如下:
spring cron表達式源碼分析

文章插圖
在CronField類中有一個內部枚舉類Type,它就是用來表示cron表達式中的字段(
在cron表達式中沒有納秒字段,其他都跟cron表達式是一一對應的

spring cron表達式源碼分析

文章插圖
先看下它的構造方法
spring cron表達式源碼分析

文章插圖
從上面也可以看到這個枚舉類有兩個字段,第一個是表示當前時間、日期的字段,后面是一個用來表示小于它的時間、日期字段的數組 。
代碼的如下圖
spring cron表達式源碼分析

文章插圖
主要代碼就是上面框出來的:
  1. 將我們傳入的cron字符串分割成數組 。
  2. 分別解析每個部分,創建CronExpression對象 。

    推薦閱讀