关于java:Spring-Boot-写定时任务发现了一个大坑

33次阅读

共计 3673 个字符,预计需要花费 10 分钟才能阅读完成。

最近栈长用 Spring Boot 写了一个定时工作:

@Scheduled(cron = "0/10 * * * * ? *")
public void execute() {...}

Spring Boot 实现定时工作的确很简略,其实是从 Spring 3.1 开始,定时工作的编写就变得非常简单,只须要几个注解就能疾速开启打算工作的反对,具体能够看这篇文章:https://mp.weixin.qq.com/s/hsuCC93OJFc8URI517-umg。

可是当我把代码写完,启动就报错:

Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method 'xxx': Cron expression must consist of 6 fields (found 7 in "0/10 * * * * ? *")
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:511) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$null$1(ScheduledAnnotationBeanPostProcessor.java:374) ~[spring-context-5.3.1.jar:5.3.1]
    at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_261]
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$postProcessAfterInitialization$2(ScheduledAnnotationBeanPostProcessor.java:374) ~[spring-context-5.3.1.jar:5.3.1]
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_261]
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:373) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:444) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:609) ~[spring-beans-5.3.1.jar:5.3.1]
    ... 16 common frames omitted

什么鬼?

谬误形容大略是说我的 Cron 表达式有问题,Cron 表达式只能由 6 位组成,但我的表达式有 7 位,不能啊,表达式也的确没问题的啊。。。

点进去看下 @Scheduled 注解的 cron 参数源码:

的确只有 6 位,并没有示意年份的占位。

持续看源码,CronSequenceGenerator 在 Spring 5.3 中曾经标识废除了,须要转到:

org.springframework.scheduling.support.CronExpression

再点进去看 CronExpression 类的源码:

6 个字段的意思很分明了,具体能够参考:

https://www.manpagez.com/man/…

示例表达式:

"0 0 * * * *" = the top of every hour of every day.
"*/10 * * * * *" = every ten seconds.
"0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day."0 0 6,19 * * *"= 6:00 AM and 7:00 PM every day."0 0/30 8-10 * * *"= 8:00, 8:30, 9:00, 9:30, 10:00 and 10:30 every day."0 0 9-17 * * MON-FRI"= on the hour nine-to-five weekdays"0 0 0 25 12 ?"= every Christmas Day at midnight"0 0 0 L * *"= last day of the month at midnight"0 0 0 L-3 * *"= third-to-last day of the month at midnight"0 0 0 1W * *"= first weekday of the month at midnight"0 0 0 LW * *"= last weekday of the month at midnight"0 0 0 * * 5L"= last Friday of the month at midnight"0 0 0 * * THUL"= last Thursday of the month at midnight"0 0 0 ? * 5#2"= the second Friday in the month at midnight"0 0 0 ? * MON#1" = the first Monday in the month at midnight

并且反对以下代替写法:

"@yearly" (or "@annually") to run un once a year, i.e. "0 0 0 1 1 *",
"@monthly" to run once a month, i.e. "0 0 0 1 * *",
"@weekly" to run once a week, i.e. "0 0 0 * * 0",
"@daily" (or "@midnight") to run once a day, i.e. "0 0 0 * * *",
"@hourly" to run once an hour, i.e. "0 0 * * * *".

如:每年:0 0 0 1 1 *,就能够写成:@yearly,除了每年,还有每月、每月、每周、每天、每小时,惋惜……没有每分、每秒!

Spring Task 咱们能够将它看成是一个轻量级的 Quartz,而且应用起来比 Quartz 要简略许多,应用了相似于 cron 的表达式,并扩大了平时的 UN*X 定义,看来和平时的 cron 表达式还不太一样,位数不同,也存在兼容问题,真坑。。。

既然晓得了问题所在,再回到之前谬误,那就只能把最初的示意 “ 年 ” 的字段去掉,6 位就够了,第 7 位不要,默认就是示意每年。

那么问题来了,我想在具体的某年,如 2025/02/25 这天执行工作,咋整?

没方法,Spring Task 不能指定年份,那就只能换成 Quartz,Quartz 也更弱小,所以,如果是简略的定时工作,Spring Task 就搞定了,简单的倡议还是应用 Quartz。

另外,留神,Spring Task 的 cron 表达式并不是齐全兼容通常的 cron 表达式,最好依据以上官网的文档来编写,免得到了线上不执行那就完蛋了。

最初,感觉我的文章对你用播种的话,动动小手,给个在看、转发,原创不易,栈长须要你的激励。

版权申明:本文系公众号 “Java 技术栈 ” 原创,原创实属不易,转载、援用本文内容请注明出处,禁止剽窃、洗稿,请自重,尊重别人劳动成果和知识产权。

近期热文举荐:

1.600+ 道 Java 面试题及答案整顿 (2021 最新版)

2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3. 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!

4.Spring Cloud 2020.0.0 正式公布,全新颠覆性版本!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0