@[TOC](@Scheduled(cron = “* * * * * *”) cron表达式通过占位符替代/设置永久不执行)

1.通过占位符写法

cron表达式不确定 springboot如何解析 设置cron表达式不执行_java

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:时区,默认为当前时区,一般没有用到。