【Spring quartz @scheduled cron 表达式不生效】

本文讲述了在实现一个定时发送邮件的功能时,遇到的Spring Scheduled Tasks与Linux crontab时间表达式不一致的问题。作者通过详细分析和测试,发现了Spring使用的是周一作为一周的第一天,而Linux中周日是一周的第一天。由此导致了任务未按预期执行。最终,作者调整了cron表达式并理解了两者之间的差异。
摘要由CSDN通过智能技术生成

背景

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

具体实现与测试

实现和测试的时候用的是
@Scheduled(fixedRate = 1000 * 60)

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

@Scheduled(cron = “0 0 10 * * 2”)

问题来了

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

重新测试

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

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

结论

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

Linux的crontab的day 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”),就大功告成了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值