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对象 。

    推荐阅读