javaspringspring-bootcronquartz

How to run methods in certain time windows


I have a microservice that will receive a message, something like this:

["00:12", "12:20", "15:40"]

Are there any out-of-the-box solutions to allow methods to run at a given time each day? Using cron from Spring does not involve changing the time at runtime. I need to use a more flexible option (change in runtime, multiple launch starts)

Thanks!


Solution

  • Spring has the @Scheduled annotation. There a several ways to configure it, one way is to configure it like unix cron job.

    For example like this:

    @Scheduled(cron = "0 15 10 15 * ?")
    public void scheduleTaskUsingCronExpression() {
     
        long now = System.currentTimeMillis() / 1000;
        System.out.println(
          "schedule tasks using cron jobs - " + now);
    }
    

    The task here is scheduled to be executed at 10:15 AM on the 15th day of every month.

    But there a also ways to configure the delay or rate dynamically at Runtime, for example like this (taken from baeldung.com):

    @Configuration
    @EnableScheduling
    public class DynamicSchedulingConfig implements SchedulingConfigurer {
    
        @Autowired
        private TickService tickService;
    
        @Bean
        public Executor taskExecutor() {
            return Executors.newSingleThreadScheduledExecutor();
        }
    
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            taskRegistrar.setScheduler(taskExecutor());
            taskRegistrar.addTriggerTask(
              new Runnable() {
                  @Override
                  public void run() {
                      tickService.tick();
                  }
              },
              new Trigger() {
                  @Override
                  public Date nextExecutionTime(TriggerContext context) {
                      Optional<Date> lastCompletionTime =
                        Optional.ofNullable(context.lastCompletionTime());
                      Instant nextExecutionTime =
                        lastCompletionTime.orElseGet(Date::new).toInstant()
                          .plusMillis(tickService.getDelay());
                      return Date.from(nextExecutionTime);
                  }
              }
            );
        }
    
    }
    

    The line Instant nextExecutionTime = ... could be replaced with your own logic for setting the next execution time, like parsing the times from your array.

    Take look at this baeldung tutorial about it: https://www.baeldung.com/spring-scheduled-tasks

    Also take look here for the cron notation: https://www.netiq.com/documentation/cloud-manager-2-5/ncm-reference/data/bexyssf.html