首页 文章

如何在 Spring 天使用@Scheduled(cron)和SpEL?

提问于
浏览
4

我有一个方法,我想要 Spring 天安排 - 为此我正在使用 @Scheduled 注释 - 更准确地说,我'm using a cron expression. My cron expression is in a property file that is called scheduler.properties. When I'米使用它作为占位符 @Scheduled(cron="${cron}") - 一切都很好;但我想使用SpEL( @Scheduled(cron="#{scheduler['cron']}") ),它不起作用 - 抛出以下异常: java.lang.IllegalArgumentException: cron expression must consist of 6 fields (found 1 in #{scheduler['cron']})

我在这做错了什么?

EDIT: 这是我的属性文件中的cron表达式: cron=0 0/1 * * * ?

这是我得到的堆栈跟踪: 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: 看起来Spring试图解析下面的字符串,因为cron表达了实际的cron表达式本身 .

4 回答

  • 1

    根据错误消息,属性文件中的cron表达式的值不正确 .

    它不符合预期的语法 .

    该值应包含六个字段,看起来像这样 .

    * 10 * * * *
    

    这是抛出此异常的代码

    /**
     * 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));
        }
    

    可能无法在Annotation中使用spEL外部化cron配置 .

    替代方案是使用XML或使用cron表达式 .

    http://forum.springsource.org/showthread.php?91203-Scheduled-and-externalization-of-configuration-for-fixedDelay-and-fixedRate-problem

  • 1

    始终在属性文件中指定如下:注意频率之间的空格 .

    每天早上9点运行刷新工作

    job.cron.rate = 0 0 9 * * *

    示例模式:

    * "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
    

    在代码中使用它:

    @Scheduled(cron = "${job.cron.rate}")    
    public void perform() throws InterruptedException {
    }
    
  • 3

    我有一个类似的问题,并通过使用context:property-placeholder读取属性文件来解决它

    <util:properties id="applicationProps" location="/WEB-INF/classes/properties/application.properties" /> **<context:property-placeholder properties-ref="applicationProps" />**

    希望它可以帮助别人!!

  • 0

    有用 . 我花了几天时间搞清楚......但这确实有效 .

    • 你应该像为JAVA_HOME等那样设置环境变量 .

    • 关闭IDE .


    export cron_scheduler_expression="0 19 21 * * *"
    

    然后重新启动IDE,Eclipse或NetBeans,无论您使用什么 .

    @Scheduled(cron = "${cron_scheduler_expression}")
    public void runSchedulerTask(){
    
    }
    

相关问题