我正在尝试在遗留 Java/Spring/Hibernate 项目中工作,所以我决定使用 spring 调度程序。
我希望 myTask.doStuff 在每个月的第一个星期日的 12:00 运行。
在我的 application-context.xml 中,我配置了我的任务调度程序,例如:
<task:scheduled-tasks scheduler="MyTaskScheduler">
<task:scheduled ref="myTask" method="doStuff" cron="0 0 12 ? 1/1 SUN#1 *"/> <!-- Every first Sundy of the month -->
</task:scheduled-tasks>
<task:scheduler id="MyTaskScheduler" pool-size="10"/>
问题 cron 表达式本身是: 0 0 12 ? 1/1 太阳#1 *
myTask
是一个 bean,它有一个名为 doStuff
的方法,在从单元测试运行时可以完美运行。
当我构建和部署时,我从 spring 中得到一个 boottime 异常:
Caused by: java.lang.IllegalArgumentException: cron expression must consist of 6 fields (found 7 in 0 0 12 ? 1/1 SUN#1 *)
at org.springframework.scheduling.support.CronSequenceGenerator.parse(CronSequenceGenerator.java:233)
at org.springframework.scheduling.support.CronSequenceGenerator.<init>(CronSequenceGenerator.java:81)
at org.springframework.scheduling.support.CronTrigger.<init>(CronTrigger.java:54)
at org.springframework.scheduling.support.CronTrigger.<init>(CronTrigger.java:44)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.afterPropertiesSet(ScheduledTaskRegistrar.java:129)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
鉴于我第一次使用 cron 表达式,我的第一个假设是我做错了什么,但我使用 cronmaker 进行了仔细检查,它给了我相同的结果。
所有文档都说:cron 表达式是由六个或七个子表达式(字段)组成的字符串。1
尽管如此,我还是尝试取消第 7 个元素(年份),因为它不在任何示例中,并且收到了不同的错误消息:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.scheduling.config.ScheduledTaskRegistrar#0': Invocation of init method failed; nested exception is java.lang.NumberFormatException: For input string: "0#1"
... org.springframework.scheduling 是否支持与其他所有内容不同的 cron 风格? the spring-specific documentation 只是说“cron 表达式”。
在这种情况下,如何让这个 cron 表达式按预期工作?任何帮助将不胜感激。
目前,我的解决方案是将这个表达式简化为只在每个星期天运行,并预先添加一些 Java 逻辑来计算它是一个月中的哪个星期天,看看这是否有效——但这有点违背了配置方法的目的和似乎是一种反模式。
0 0 12 ? * SUN#1
吗? (没有最后一个 *
)
Spring 计划任务与 cron 表达式的格式不同。
它们不遵循与 UNIX cron 表达式相同的格式。
只有6个字段:
第二,
分钟,
小时,
一个月的一天,
月,
星期几。
星号 (*) 表示匹配任何内容。 */X 表示“每个 X”(参见示例)。
一周中的数字天数对我不起作用。此外,“MON-FRI”更容易阅读。以下是一些示例表达式:
"0 0 18 * * MON-FRI" means every weekday at 6:00 PM.
"0 0 */1 * * *" means every hour on the hour.
"0 0 */8 * * *" means every 8 hours on the hour.
"0 0 12 1 * *" means 12:00 PM on the first day of every month.
在这里您可以找到一些additional information。
您还可以找到 spring documentation useful。
记录以下内容:https://www.baeldung.com/cron-expressions
Spring 计划任务是这样的:
1 2 3 4 5 6 Index
- - - - - -
* * * * * * command to be executed
- - - - - -
| | | | | |
| | | | | ------- Day of week (MON - SUN)
| | | | --------- Month (1 - 12)
| | | ----------- Day of month (1 - 31)
| |-------------- Hour (0 - 23)
| --------------- Minute (0 - 59)
----------------- Seconds (0 - 59)
来自:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/
Linux Cron 作业是这样的:
1 2 3 4 5 Index
- - - - -
* * * * * command to be executed
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)
边注:
一些文章说可以有一个 7 可选参数是 year ,我尝试使用最新的 spring 并且它显示错误,所以我认为它不起作用。
如果您的 Linux cron 作业表达式足够简单,似乎可以在前面放一个 0,它会转换为 spring 计划任务表达式,例如每 5 分钟 */5 * * * * Linux cron 作业 0 */5 * * * * 春季计划任务
例如每 5 分钟 */5 * * * * Linux cron 作业 0 */5 * * * * Spring 调度任务
*/5 * * * * Linux cron 作业
*/5 * * * * 春季调度任务
奖励:Spring Schedule Cron 生成器
单击显示代码片段 单击运行代码片段 玩得开心!
$('.select2').select2({ width: '100%' }); //// 初始化 /////////// $dropdown = $("#secondsSelect"); for (let i = 1; i < 60; i++) { $dropdown.append($("").val(i).text(i)); } $dropdown = $("#minSelect"); for (let i = 1; i < 60; i++) { $dropdown.append($("").val(i).text(i)); } $dropdown = $("#hoursSelect"); for (let i = 1; i < 24; i++) { $dropdown.append($("").val(i).text(i)); } $dropdown = $("#dayOfMonthSelect"); for (let i = 1; i < 32; i++) { $dropdown.append($("").val(i).text(i)); } //// 初始化结束 //////////// $('.select2').on('select2:select', function(e) { let value = e.params.data.id ; 让 prevValue = $(this).val().length > 0 ? $(this).val()[0] : null; if (value != parseInt(value)) { $(this).val(value ).change(); } else if (prevValue != parseInt(prevValue)) { $(this).val(value).change(); } calculateSpringCron(); });让 r = function(dropdown) { return dropdown.val().join(","); } let calculateSpringCron = function() { let result = [ r($("#secondsSelect")), r($("#minSelect")), r($("#hoursSelect")), r($(" #dayOfMonthSelect")), r($("#monthsSelect")), r($("#weekdaySelect")), ]; $("#result").val(result.join(" ")); $("#result-expand").html(result.join(" ")) } calculateSpringCron(); .ms-container { 显示:弹性;弹性方向:列;宽度:100%;左填充:3em;填充权:3em;背景:无!重要;底部填充:5em; }
@Recurring(id = "my-recurring-job", cron = "*/5 * * * *")
。最大的好处是它带有一个 handy dashboard 来显示您的 CRON 作业是否成功。