Spring quartz @scheduled cron 表达式不生效

Spring cron 表达式不生效

Posted by chyuan on 2022-11-14
Estimated Reading Time 3 Minutes
Words 835 In Total

背景

最近要做一个定时的邮件发送的功能,定期在周一上午10点发送。

具体实现与测试

实现和测试的时候用的是

1
@Scheduled(fixedRate = 1000 * 60)

意为每隔60秒执行一遍任务,用以上表达式,一切OK,轻松加愉快的敲完了实现发送的代码,BingGo,测试通过后。最后需要上生产了,其他代码全没改,就改成cron,如下:

1
@Scheduled(cron = "0 0 10 * * 2")

问题来了

将表达式改成了@Scheduled(cron = "0 0 10 * * 2")后,坐等生产上定时发送,叮叮~~到了10点过1分的时候,用户写邮件问我,嗨,小王(化名)在吗?我们没有收到邮件,可以看一下有神马问题吗?我一下就惊了,立马坐起来了,因为我没有在本地测试过@Scheduled(cron = "0 0 10 * * 2")

重新测试

1
@Scheduled(cron = "0 3 10 * * 2")

我接到问题的时候是10点1分,于是我在本地设置了10点3分,坐等任务触发,d=====( ̄▽ ̄*)b,时间到了,可是没有进入我的断点。内心有点崩溃,找了各种cron在线表达式验证,如下:
在这里插入图片描述
在这里插入图片描述

今天是8月1日,而现在的时间超过了10点,今天也是星期一,故没有今天的时间,但可以从预测推断出,今天上午应该会执行。最后的数字2代表一周的第几天,礼拜天是第1天,所以周一是第2天,故我这写的2,在线检查的网站也肯定了我的写法。

结论

到此,我有点抓狂,不知道为什么死活不会进我的断点。于是疯狂的面向搜索引擎搜索,直到我看到了这个:
在这里插入图片描述
突然,仿佛看到了一束光,我的天呐,原来这俩玩意的起点不一样,想骂街了都。

Linuxcrontabday of week是从周天算起,但是spring scheduled tasks却是从周一算起,到此基本知道为啥会进入不了我的断点了,因为按照表达式@Scheduled(cron = "0 3 10 * * 2")的写法,我需要在明天也就是周二debug的时候才能进断点。

缘由

但这还是不够,我想知道为什么spring scheduled会整这个反人类的设计,于是我想到了去看关于这块实现的源码,于是我找到这个:
https://github.com/spring-projects/spring-framework/blob/6e4551131dddffecd7adc00d96e3ecddd4c4911c/spring-context/src/main/java/org/springframework/scheduling/support/QuartzCronField.java
在这里插入图片描述
DayOfWeek 来自java.time.DayOfWeek 是一个枚举类型

在网上搜索发现:
https://docs.oracle.com/javase/8/docs/api/java/time/DayOfWeek.html
在这里插入图片描述
在这里有描述:
In addition to the textual enum name, each day-of-week has an int value. The int value follows the ISO-8601 standard, from 1 (Monday) to 7 (Sunday). It is recommended that applications use the enum rather than the int value to ensure code clarity.

This enum provides access to the localized textual form of the day-of-week. Some locales also assign different numeric values to the days, declaring Sunday to have the value 1, however this class provides no support for this.

从这里找到源头了,1代表Monday,并且也说明了在有些地方会用1代表周天,但是在DayOfWeek这个类里,并不支持这种说法。

至此,我把@Scheduled(cron = "0 0 10 * * 2")换成了@Scheduled(cron = "0 0 10 * * 1"),就大功告成了。


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !