Search code examples
springspring-bootcronjob-schedulingspring-scheduled

How to schedule a cron job in spring boot without using @Scheduled() annotation


In spring boot, can I schedule a spring job by not using @Scheduled annotation to a method?

I am working with spring job in the spring boot. I want to schedule a job by using cron expression, but without using @Scheduled(cron = " ") annotation to the method.

I know that I can schedule a job inside this method as below.

@Scheduled (cron = "0 10 10 10 * ?")

public void execute() { 

   / * some job code * /

}

But I want it to be dynamic so that I can take a cron expression as input from the user and schedule it.


Solution

  • I came up with a working example since I found your question interesting and have been interested in this problem before. It's based entirely on the source code so I have no idea if it comes close to following best practice. Nonetheless, you may be able to tune it to your needs. FYI, you don't necessarily need to create a new ScheduledTaskRegistrar object - I figured that since your objective is a dynamic scheduler, you wouldn't be interested in defining your tasks purely in the overwritten method.

    @SpringBootApplication
    public class TaskScheduler implements SchedulingConfigurer, CommandLineRunner {
    
        public static void main(String[] args){SpringApplication.run(TaskScheduler.class, args);}
    
        List<CronTask> cronTasks;
    
        @Override
        public void run(String... args) throws Exception {
            CronTask task = this.createCronTask(new Runnable() {
                @Override
                public void run() {
                    System.out.println(LocalDateTime.now());
                }
            }, "1/10 * * * * *");
    
            ScheduledTaskRegistrar taskRegistrar = new ScheduledTaskRegistrar();
            taskRegistrar.addCronTask(task);
            configureTasks(taskRegistrar);
            Thread.sleep(51);
    
            taskRegistrar.destroy();
            taskRegistrar = null;
    
            ScheduledTaskRegistrar taskRegistrar2 = new ScheduledTaskRegistrar();
            taskRegistrar2.addCronTask(task);
            configureTasks(taskRegistrar2);
    
        }
    
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            // "Calls scheduleTasks() at bean construction time" - docs
            taskRegistrar.afterPropertiesSet();
        }
    
        public CronTask createCronTask(Runnable action, String expression) {
            return new CronTask(action, new CronTrigger(expression));
        }
    
    }
    

    I have experience using cron jobs in Azure and other places. Programming in Java, I have typically used @Scheduled with fixed times just for the sake of simplicity. Hope this is useful to you though.