java 如何在 Spring 中将 @Scheduled(cron) 与 SpEL 一起使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10394716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use @Scheduled(cron) with SpEL in spring?
提问by Noam
I have a method that I want spring to schedule - for that matter I'm using the @Scheduled
annotation - and to be more exact, I'm using a cron expression.
My cron expression is in a property file that is called scheduler.properties.
When I'm using it as a placeholder @Scheduled(cron="${cron}")
- everything works great; but I want to use SpEL ( @Scheduled(cron="#{scheduler['cron']}")
) , and it does't work - throws the following exception:java.lang.IllegalArgumentException: cron expression must consist of 6 fields (found 1 in #{scheduler['cron']})
我有一个我希望 spring 安排的方法 - 就此而言,我正在使用@Scheduled
注释 - 更准确地说,我正在使用 cron 表达式。我的 cron 表达式位于名为 scheduler.properties 的属性文件中。当我将它用作占位符时@Scheduled(cron="${cron}")
- 一切都很好;但我想使用 SpEL ( @Scheduled(cron="#{scheduler['cron']}")
) ,但它不起作用 - 引发以下异常:java.lang.IllegalArgumentException: cron expression must consist of 6 fields (found 1 in #{scheduler['cron']})
What am I doing wrong here?
我在这里做错了什么?
EDIT:Here is my cron expression from the properties file: cron=0 0/1 * * * ?
编辑:这是我的属性文件中的 cron 表达式:cron=0 0/1 * * * ?
Here is the stack trace that I get:
java.lang.IllegalArgumentException: cron expression must consist of 6 fields (found 1 in #{scheduler['cron']})
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:188)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:209)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:1)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:97)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:324)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:929)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:467)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:384)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
这是我得到的堆栈跟踪:
java.lang.IllegalArgumentException: cron expression must consist of 6 fields (found 1 in #{scheduler['cron']})
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:188)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:209)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:1)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:97)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:324)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:929)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:467)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:384)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
SECOND EDIT:It seems that spring is trying to parse the following string as the cron experssion "#{scheduler['cron']}" insraed of the actual cron expression itself.
第二次编辑:spring 似乎试图将以下字符串解析为实际 cron 表达式本身的 cron 表达式“#{scheduler['cron']}”。
采纳答案by Rob Kielty
According to the error message, the value of the cron expression in your properties file is incorrect.
根据报错信息,你的properties文件中cron表达式的值不正确。
It does not conform to the expected syntax.
它不符合预期的语法。
The value should contain six fields and look something like this.
该值应包含六个字段,如下所示。
* 10 * * * *
Here's the code that throws this exception
这是引发此异常的代码
/**
* Parse the given pattern expression.
*/
private void parse(String expression) throws IllegalArgumentException {
String[] fields = StringUtils.tokenizeToStringArray(expression, " ");
if (fields.length != 6) {
throw new IllegalArgumentException(String.format(""
+ "cron expression must consist of 6 fields (found %d in %s)", fields.length, expression));
}
It may not be possible to externalize cron configuration using spEL in an Annotation.
可能无法在 Annotation 中使用 spEL 将 cron 配置外部化。
The alternatives are to use XML or use the cron expression.
替代方法是使用 XML 或使用 cron 表达式。
回答by Kul Bhushan Prasad
Always specify like this in property file: Notice the space in between frequency.
在属性文件中总是这样指定:注意频率之间的空间。
run refresh job every day a 9am
每天早上 9 点运行刷新作业
job.cron.rate=0 0 9 * * *
job.cron.rate=0 0 9 * * *
Example patterns:
示例模式:
* "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/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock 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
Use it like this in Code:
在代码中像这样使用它:
@Scheduled(cron = "${job.cron.rate}")
public void perform() throws InterruptedException {
}
回答by Ashu
I had a similar issue and resolved it by reading property file with context:property-placeholder
我遇到了类似的问题,并通过使用 context:property-placeholder 读取属性文件来解决它
<util:properties id="applicationProps" location="/WEB-INF/classes/properties/application.properties" />
**<context:property-placeholder properties-ref="applicationProps" />**
<util:properties id="applicationProps" location="/WEB-INF/classes/properties/application.properties" />
**<context:property-placeholder properties-ref="applicationProps" />**
Hope it helps someone!!
希望对某人有帮助!!
回答by user1842915
It works. I spent days figuring out... but this indeed works.
有用。我花了几天时间弄清楚……但这确实有效。
- You should set environment variable like you do for JAVA_HOME etc.
- Close your IDE.
- 您应该像为 JAVA_HOME 等设置环境变量。
- 关闭您的 IDE。
export cron_scheduler_expression="0 19 21 * * *"
Then restart your IDE, Eclipse or NetBeans whatever you are using.
然后重新启动您的 IDE、Eclipse 或 NetBeans,无论您使用的是什么。
@Scheduled(cron = "${cron_scheduler_expression}")
public void runSchedulerTask(){
}