当前位置: 首页 > 知识库问答 >
问题:

在@Scheduler中动态更改cron表达式的Spring Boot

柴博
2023-03-14

我有一些时间

LocalTime [] slots = {LocalTime.of(0, 0), LocalTime.of(7, 0), LocalTime.of(13, 0), LocalTime.of(19, 0)}

现在的条件是,当JVM启动时,它将首先检查当前时间和给定时隙的持续时间。下面是检查时长的方法:-

public static Duration findNextSlotDuration(LocalTime now, LocalTime [] slots) {            
        Duration duration = null;
        if(slots != null)
        {
            if(slots.length == 1)
            {
                duration = Duration.between(now, slots[0]);
            }else if(slots.length > 1)
            {
                for (int i = 0; i < slots.length-1; i++) {
                        if(isBetween(now, slots[i], slots[i+1]))   
                        {
                            duration = Duration.between(now, slots[i+1]); 
                            break;
                        }
                }
            }               
            if(duration != null && !duration.isNegative())  
                return duration;
            else 
            {
                Duration d1 = Duration.between(now, LocalTime.of(23, 59)).plusMinutes(1);
                Duration d2 =  Duration.between(LocalTime.of(0, 0), slots[0]); 
                return d1.plus(d2); 
            }
        }       
        return Duration.ofMinutes(5);   
    }


 private static boolean isBetween(LocalTime candidate, LocalTime start, LocalTime end) {
      return !candidate.isBefore(start) && !candidate.isAfter(end);  // Inclusive.
  }

例如,如果JVM在今天17PM开始,那么它将首先检查时隙,它将得到13PM到19PM之间的时隙,并且根据方法findNextSlotDuration将是2小时,因此调度器将在2小时后开始,即在19PM。另一种情况是,如果JVM今天在19小时00分29秒启动,那么它将得不到插槽,那么持续时间将是6小时00分29秒,那么调度程序在00:00:29时启动。

所以我想知道如何在Spring Boot中用Cron实现@Scheduler或任何更好的方法。

共有1个答案

柏高洁
2023-03-14

首先,如果我理解正确的话,我会试着给你一些建议。希望对你有帮助

您可以捕获应用程序就绪事件,如下所示,并且您可以在任何时候实现您想要执行的事件。此外,您还可以使用此方法触发您的方法。

@Component
public class AppReadyComponent implements ApplicationListener<ApplicationReadyEvent> {

  @Override
  public void onApplicationEvent(ApplicationReadyEvent event) {
    // some logic
  }
}

最后,您可以动态计算cron值,并使用它触发您的调度方法,如下所示。

@SpringBootApplication
public class MainApp {

  @Bean
  public String getCronValue() {
    // here you may calculate cron value dynamically and return it as a string
    return cronValue;
  }
}
@Scheduled(cron = "#{@getCronValue}")
public void process() {
   // some logic
}
 类似资料:
  • 问题内容: 我能够在applicationContext.xml中创建taskScheduler,并且根据该属性定期触发我的工作。 我想在调度程序启动后更改此表达式(触发时间),这意味着JavaEE应用程序正在运行。 使用Spring 3.XX 问题答案: 其实我也遇到过同样的问题 我假设您需要从用户那里获取date(1-31),时间,星期几,调度程序的类型(每日,每月,每周)。 首先,您需要根据

  • 我正在尝试在特定时间调用API。但有时api调用可能会失败,所以我制定了一个逻辑来检查api调用何时失败。 确认api调用失败后,我想将@Schedulercron表达式从当前cron表达式更改为15分钟后。 如何动态更改cron表达式?? 下面是我的API调用代码。

  • 我试图在集群模式下使用camel-quartz2组件和jdbcjobstore。 quartz.properties文件: 或者,我可以为camel-quartz2组件打补丁,如下所示(org.apache.camel.component.quartz2.quartzendpoint#AddJobInScheduler): 与项目存储库中的当前版本不同,我的版本总是创建新的触发器,如果触发器已经存

  • 我有点卡在最新的石英2.2和spring 4.1上...这里有一个cron触发器,为了清楚起见,我省略了这个工作和其他一些琐碎的事情: 现在,我需要在运行时更改它的cronExpression,而且这并不像我想象的那么简单。我无法引用bean并更改属性,因为它是一个提供CronTrigger接口的工厂,而CronTrigger接口不再具有setCronExpression方法,它已经变得不可变。然

  • 我正在使用石英调度程序来安排我的工作。我有一个错误的cron表达式: 当我这样做的时候: is。但是当我查看表达式时,它显然是错误的。其他人也面临类似的问题吗? 注:包装为:包装组织。石英 石英的版本是:2.2.3 请检查来自的CronExpression类http://www.javadoc.io/doc/org.quartz-scheduler/quartz/2.2.3 我还尝试了类的方法,但

  • 我试图在Java中使用quartz构建一个cron表达式。我得到了小时和分钟两个参数,我必须用它们来每小时和每分钟安排一个作业。到目前为止,我已经尝试过了:示例1:-计划作业每1小时10分钟运行一次。-我在这个例子中使用了cron表达式“0*/10*/1**?”。-但这项工作每10分钟运行一次,而不是1小时10分钟。 谁能帮我理解为什么这个表达不起作用?提前谢了。