我使用
@Scheduled
注释和 cron 表达式来安排工作日期间的重复任务。我想做的是在 8:00 运行第一个作业,然后每 15 分钟在 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 should be okay unless something else has already gone terribly wrong.
因此有可用的解决方法,但我认为用一个表达式来统治所有这些是最优雅的。问题是,我无法找到一种方法来获得 17:00 的调用,而不同时获得 17:15、17:30 和 17:45。
在 17:00 整结束比在 8:00 整开始更重要,因此从 8:15 开始到 17:00 结束的表达式对于此特定目的来说是可以的。我也不知道如何将其放入 cron 表达式中。
有可能吗,只是我太盲目了,看不到路,还是我找错了树?如果是后者,是否有另一种优雅的方式来获得我想要的调用模式?
从
CronExpression
javadoc 来看,spring 只是实现了 this 中描述的 crontab 表达式。阅读此手册页,不要认为它有一些特殊的语法,允许仅使用单个表达式来表示您的用例。因此,像您当前所做的那样用两个表达式来表示它对我来说已经是最简单、最优雅的开箱即用解决方案。
如果您确实想在
application.properties
中的一行中定义所有 cron 表达式,您可以在 application.properties
中将其定义为 CSV 值,然后逐一读取该值,并通过以下方式以编程方式为每个值注册 cron 作业:实施SchedulingConfigurer
(请参阅this)。
类似的东西:
应用程序属性:
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(){
........
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
for(String cron : crontabs){
taskRegistrar.addCronTask(()->runCronJob() , cron);
}
}
}