代码之家  ›  专栏  ›  技术社区  ›  Wintermute

Spring Boot@Scheduled annotation:开始和结束在小时的顶部?

  •  0
  • Wintermute  · 技术社区  · 2 年前

    我正在使用 @Scheduled 带有cron表达式的注释,以便在工作日安排重复任务。我想做的是在8:00运行第一个作业,然后每15分钟运行一次,直到17:00(包括17:00)。我可以很容易地在8:00到16:45之间获得作业,但最后一个(至关重要的)调用让我措手不及。有可能在cron表达式中做到这一点吗?

    现在我使用两个函数,一个用

    @Scheduled(cron = "0 */15 8-16 * * MON-FRI")
    

    另一个

    @Scheduled(cron = "0 0 17 * * MON-FRI")
    

    后者简称前者。这是可行的,但理想情况下,我希望在 application.properties 只有一个表达式。

    我还考虑过每15分钟运行一次作业,配置开始和结束时间,并检查系统时间是否在配置的间隔内。这让我觉得有点难看,因为17:00调用将在17:00加上未指定的时间量进行检查,但在实践中,该时间量应该很小,并且检查<17:01应该没问题,除非其他事情已经出了严重问题。

    所以有一些变通方法,但我认为用一个表达式来统治所有这些方法是最优雅的。问题是,如果没有17:15、17:30和17:45,我无法找到一种方法来获得17:00的调用。

    17点整结束比8点整开始更重要,因此从8点15分开始到17点结束的表达式可以用于此特定目的。我也不知道如何将其转化为cron表达式。

    这可能吗?我只是太瞎了,看不见路,还是我找错树了?如果是后者,是否还有其他优雅的方法可以获得我想要的调用模式?

    0 回复  |  直到 2 年前
        1
  •  1
  •   Ken Chan    2 年前

    来自 CronExpression javadoc,spring只是实现了上面描述的crontab表达式 this 。阅读此手册页时,不要认为它有一些特殊的语法可以只使用一个表达式来表示您的用例。因此,用两个表达式来表示它,就像你目前所做的那样,对我来说已经是最简单、最优雅的开箱即用解决方案了。

    如果您真的想在中的一行中定义所有cron表达式 application.properties ,您可以在中将其定义为CSV值 application.properties 然后逐个读取cron表达式,并通过实现以编程方式为每个表达式注册一个cron作业 SchedulingConfigurer (请参阅 this )。

    类似于:

    application.properties:

    app.crontabs=0 */15 8-16 * * MON-FRI,0 0 17 * * MON-FRI
    

    以及应用程序配置:

    @EnableScheduling
    @Configuration
    public class CronJobConfig implements SchedulingConfigurer {
    
       
        @Value("${app.crontabs}")
        private List<String> crontabs;
    
    
        @Bean(destroyMethod = "shutdown")
        public Executor taskExecutor() {
            return Executors.newScheduledThreadPool(100);
        }
    
        private void runCronJob(){
          //your cron job
        }
    
       
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            taskRegistrar.setScheduler(taskExecutor());
            for(String cron : crontabs){
                taskRegistrar.addCronTask(()->runCronJob() , cron);
            }
        }
    }