@[TOC](@Scheduled(cron = “* * * * * *”) cron表达式通过占位符替代/设置永久不执行)
1.通过占位符写法
2.设置永久不执行
2.1设置成去年,让其不执行
报错:
Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method 'startDataCollect': Range exceeds maximum (8): '2019' in expression "* * * * * 2019"
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:496)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$null$1(ScheduledAnnotationBeanPostProcessor.java:359)
at java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$postProcessAfterInitialization$2(ScheduledAnnotationBeanPostProcessor.java:359)
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:358)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:429)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
... 15 common frames omitted
原因:第7位参数为年份,第六位代表星期(1-7)
cron表达式格式: {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}
秒 :可以用数字0-59 表示;
分 :可以用数字0-59 表示;
时:可以用数字0-23表示;
天:可以用数字1-31 中的任一一个值,但要注意一些特别的月份2月份没有只能1-28,有些月份没有31;
月:可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示;
周:可以用数字1-7表示(1 = 星期日)或用字符口串"SUN, MON, TUE, WED, THU, FRI and SAT"表示;
“-”:区间连接,0-10 * * * * 表示0-10秒的时候执行
“,”:多个时间点,0,10 * * * * * 表示0和10秒的时候执行
“/”:为特别单位,表示为"每"如"0/10"表示每隔10分钟执行一次,“0"表示为从"0"分开始, “3/20"表示表示每隔20分钟执行一次,“3"表示从第3分钟开始执行;
“?”:表示每月的某一天,或第周的某一天;
“L”:用于每月,或每周,表示为每月的最后一天,或每个月的最后星期几如"6L"表示"每月的最后一个星期五”;
“W”:表示为最近工作日,如"15W"放在每月(day-of-month)字段上表示为"到本月15日最近的工作日”;
“#”:是用来指定"的"每月第n个工作日,例 在每周(day-of-week)这个字段中内容为"6#3” or “FRI#3” 则表示"每月第三个星期五";
“*” 代表整个时间段。
2.2改成7个参数,最后一位放年份
依然报错:
Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method 'startDataCollect': Cron expression must consist of 6 fields (found 7 in "* * * * * * 2019")
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:496)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$null$1(ScheduledAnnotationBeanPostProcessor.java:359)
at java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$postProcessAfterInitialization$2(ScheduledAnnotationBeanPostProcessor.java:359)
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:358)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:429)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
... 15 common frames omitted
原因:Spring3.0的版本后,cron表达式只能支持6个字段
2.3设置成不存在的日期,比如9月31号
报错:
2021-10-11 11:35:41.590 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.IllegalArgumentException: Invalid cron expression "* * * 31 9 *" led to runaway search for next trigger
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:201)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:194)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:204)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:194)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:204)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:194)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:204)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:194)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:204)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:194)
at org.springframework.scheduling.support.CronSequenceGenerator.next(CronSequenceGenerator.java:148)
at org.springframework.scheduling.support.CronTrigger.nextExecutionTime(CronTrigger.java:87)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.schedule(ReschedulingRunnable.java:75)
at org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler.schedule(ThreadPoolTaskScheduler.java:313)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleCronTask(ScheduledTaskRegistrar.java:414)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleTasks(ScheduledTaskRegistrar.java:352)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.afterPropertiesSet(ScheduledTaskRegistrar.java:332)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.finishRegistration(ScheduledAnnotationBeanPostProcessor.java:300)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:231)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:103)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:896)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:163)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at com.copote.data.manager.metabase.api.MetabaseApplication.main(MetabaseApplication.java:26)
原因:CronSequenceGenerator的doNext算法从指定时间开始(包括指定时间)查找符合cron表达式规则下一个匹配的时间。匹配不到抛异常
2.4日期范围(1-31),设置成0,不报错,不执行
报错:
2021-10-11 11:42:04.364 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.IllegalArgumentException: Overflow in day for expression "* * * 0 * *"
at org.springframework.scheduling.support.CronSequenceGenerator.findNextDay(CronSequenceGenerator.java:223)
at org.springframework.scheduling.support.CronSequenceGenerator.doNext(CronSequenceGenerator.java:189)
at org.springframework.scheduling.support.CronSequenceGenerator.next(CronSequenceGenerator.java:148)
at org.springframework.scheduling.support.CronTrigger.nextExecutionTime(CronTrigger.java:87)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.schedule(ReschedulingRunnable.java:75)
at org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler.schedule(ThreadPoolTaskScheduler.java:313)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleCronTask(ScheduledTaskRegistrar.java:414)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleTasks(ScheduledTaskRegistrar.java:352)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.afterPropertiesSet(ScheduledTaskRegistrar.java:332)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.finishRegistration(ScheduledAnnotationBeanPostProcessor.java:300)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:231)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:103)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:896)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:163)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at com.copote.data.manager.metabase.api.MetabaseApplication.main(MetabaseApplication.java:26)
原因同4
3.讨论
Linux 的crontab未尝试上面方法,不知是否可行,使用的springboot 5.1.5试了几种方法都不行,实际运用中如果永久停,代码肯定要拿掉,所以不再纠结了,有懂的欢迎执教!
4.其它
scheluer 源码
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.scheduling.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* An annotation that marks a method to be scheduled. Exactly one of
* the {@link #cron()}, {@link #fixedDelay()}, or {@link #fixedRate()}
* attributes must be specified.
*
* <p>The annotated method must expect no arguments. It will typically have
* a {@code void} return type; if not, the returned value will be ignored
* when called through the scheduler.
*
* <p>Processing of {@code @Scheduled} annotations is performed by
* registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be
* done manually or, more conveniently, through the {@code <task:annotation-driven/>}
* element or @{@link EnableScheduling} annotation.
*
* <p>This annotation may be used as a <em>meta-annotation</em> to create custom
* <em>composed annotations</em> with attribute overrides.
*
* @author Mark Fisher
* @author Juergen Hoeller
* @author Dave Syer
* @author Chris Beams
* @since 3.0
* @see EnableScheduling
* @see ScheduledAnnotationBeanPostProcessor
* @see Schedules
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
/**
* A special cron expression value that indicates a disabled trigger: {@value}.
* <p>This is primarily meant for use with ${...} placeholders, allowing for
* external disabling of corresponding scheduled methods.
* @since 5.1
*/
String CRON_DISABLED = "-";
/**
* A cron-like expression, extending the usual UN*X definition to include triggers
* on the second as well as minute, hour, day of month, month and day of week.
* <p>E.g. {@code "0 * * * * MON-FRI"} means once per minute on weekdays
* (at the top of the minute - the 0th second).
* <p>The special value {@link #CRON_DISABLED "-"} indicates a disabled cron trigger,
* primarily meant for externally specified values resolved by a ${...} placeholder.
* @return an expression that can be parsed to a cron schedule
* @see org.springframework.scheduling.support.CronSequenceGenerator
*/
String cron() default "";
/**
* A time zone for which the cron expression will be resolved. By default, this
* attribute is the empty String (i.e. the server's local time zone will be used).
* @return a zone id accepted by {@link java.util.TimeZone#getTimeZone(String)},
* or an empty String to indicate the server's default time zone
* @since 4.0
* @see org.springframework.scheduling.support.CronTrigger#CronTrigger(String, java.util.TimeZone)
* @see java.util.TimeZone
*/
String zone() default "";
/**
* Execute the annotated method with a fixed period in milliseconds between the
* end of the last invocation and the start of the next.
* @return the delay in milliseconds
*/
long fixedDelay() default -1;
/**
* Execute the annotated method with a fixed period in milliseconds between the
* end of the last invocation and the start of the next.
* @return the delay in milliseconds as a String value, e.g. a placeholder
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
* @since 3.2.2
*/
String fixedDelayString() default "";
/**
* Execute the annotated method with a fixed period in milliseconds between
* invocations.
* @return the period in milliseconds
*/
long fixedRate() default -1;
/**
* Execute the annotated method with a fixed period in milliseconds between
* invocations.
* @return the period in milliseconds as a String value, e.g. a placeholder
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
* @since 3.2.2
*/
String fixedRateString() default "";
/**
* Number of milliseconds to delay before the first execution of a
* {@link #fixedRate()} or {@link #fixedDelay()} task.
* @return the initial delay in milliseconds
* @since 3.2
*/
long initialDelay() default -1;
/**
* Number of milliseconds to delay before the first execution of a
* {@link #fixedRate()} or {@link #fixedDelay()} task.
* @return the initial delay in milliseconds as a String value, e.g. a placeholder
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
* @since 3.2.2
*/
String initialDelayString() default "";
}
1.cron:cron表达式,指定任务在特定时间执行;
2.fixedDelay:表示上一次任务执行完成后多久再次执行,参数类型为long,单位ms;
3.fixedDelayString:与fixedDelay含义一样,只是参数类型变为String;
4.fixedRate:表示按一定的频率执行任务,参数类型为long,单位ms;
5.fixedRateString: 与fixedRate的含义一样,只是将参数类型变为String;
6.initialDelay:表示延迟多久再第一次执行任务,参数类型为long,单位ms;
7.initialDelayString:与initialDelay的含义一样,只是将参数类型变为String;
8.zone:时区,默认为当前时区,一般没有用到。