DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Calling a Client Via Spring @schedule Cron Job
  • Distributed Task Synchronization: Leveraging ShedLock in Spring
  • External Task Client Implementation in Camunda With Spring Boot Application
  • Actuator Enhancements: Spring Framework 6.2 and Spring Boot 3.4

Trending

  • Why Pass/Fail CI Pipelines Are Insufficient for Enterprise Release Decisions
  • Securing Everything: Mapping the Right Identity and Access Protocol (OIDC, OAuth2, and SAML) to the Right Identity
  • The Hidden Bottlenecks That Break Microservices in Production
  • Agentic Testing: Moving Quality From Checkpoint to Control Layer
  1. DZone
  2. Coding
  3. Frameworks
  4. Dynamically Schedule the Same Task with Multiple Cron Expression Using Spring Boot

Dynamically Schedule the Same Task with Multiple Cron Expression Using Spring Boot

Learn how to schedule a task with multiple cron expressions with Spring Boot and schedule them using ScheduledTaskRegistrar.

By 
Ramesh Silamala user avatar
Ramesh Silamala
·
Apr. 28, 20 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
95.9K Views

Join the DZone community and get the full member experience.

Join For Free

We have seen how to schedule a task within Spring or Spring Boot using a cron expression, with fixed delays. In this in this tutorial, we will see how to schedule a task with multiple cron expressions and change the cron expression on the fly without restarting the server.

Creating a cron trigger task with Spring is pretty easy by adding a @Scheduled annotation to any method and adding @EnableScheduling in any configuration file. But here we use  org.springframework.scheduling.annotation.SchedulingConfigurer  interface . SchedulingConfigurer class has one method,configureTasks(ScheduledTaskRegistrar taskRegistrar) which will be called at the time of bootstrap and register the tasks.

Here, with the help of ScheduledTaskRegistrar, we schedule the task to run at particular time intervals or with fixed rate delays. 

First, we need to implement the SchedulingConfigurer interface where we need to schedule the cron tasks. Refer to the below code to see how to do that.

Java
 




xxxxxxxxxx
1
28
9


 
1
@Configuration
2
@EnableScheduling
3
public class SchedulerConfig implements SchedulingConfigurer {
4
  @Override
5
  public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
6

          
7
    }
8
}


ScheduledTaskRegistrar has multiple override methods to schedule the task. Here I am going to use the   addTriggerTask(Runnable task, Trigger trigger)  which will take Runnable task which we want to schedule and a Trigger at which intervals the task has to be triggered.

ScheduledTaskRegistrar internally implements the InitializingBean so upon creating the bean, it will call the overriden afterProperties method which will start scheduling the added triggered tasks using ScheduledExecutorService and TaskScheduler. See how to add a trigger task using ScheduledTaskRegistrar below.

Java
 




x





1
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
2

          
3
        Runnable runnable = () -> System.out.println("Trigger task executed at " + new Date());
4

          
5
  Trigger trigger = new Trigger() {
6
    @Override
7

          
8
            public Date nextExecutionTime(TriggerContext triggerContext) {
9

          
10
                CronTrigger crontrigger = new CronTrigger("0 0/1 * * * *");
11

          
12
                return crontrigger.nextExecutionTime(triggerContext);
13

          
14
            }
15

          
16
        };
17

          
18
        scheduledTaskRegistrar.addTriggerTask(runnable, trigger);
19

          
20
    }
21

          


With the above code, the runnable task executes at every one minute. 

Now, let's see how to schedule the same task with two or more cron expressions. Here I am taking the list of cron expressions separated with the pipe symbol. In this code, I am running a loop inside the configureTasks to add the trigger for each cron in the list of cron expressions.

Java
 




xxxxxxxxxx
1
29


 
1
String cronsExpressions = "0 0/1 * * * * | 0 0/5 * * * * | 0 0/10 * * * *";
2

          
3
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { 
4

          
5
// Split the cronExpression with pipe and for each expression add the same task.
6
    Stream.of(StringUtils.split(cronsExpressions, "|")).forEache(cronExpression -> { 
7

          
8
         Runnable runnable = () -> System.out.println("Trigger task executed at " + new Date());
9

          
10
                      Trigger trigger = new Trigger() {
11

          
12
                        @Override
13

          
14
                        public Date nextExecutionTime(TriggerContext triggerContext) {
15

          
16
                            CronTrigger crontrigger = new CronTrigger(cronExpression);
17

          
18
                            return crontrigger.nextExecutionTime(triggerContext);
19

          
20
                        }
21

          
22
                    };
23

          
24
               scheduledTaskRegistrar.addTriggerTask(runnable, trigger);
25

          
26
}
27

          
28
}
29

          



With the above code, the runnable task excutes every minute or every 5 or 10 minutes all the time.

Now, to change the task to run at every 2, 7, or 9 minutes all the time and the stop the triggers added for evey 1, 5, or 10 minutes but without having to restart my server. Here the configureTasks will be called during the bootstrap only, but how do we do that now by stopping the existing triggers and creating new trigger task with new cron expressions?

First I will maintain a database property where I will have the cron expression separated by the pipe symbol so that I can change the cron expression on the fly without changing the server.

During the every trigger time I will check the cron expression modified by pulling the cron from data base.

If there is a change in the cron expression, it will stop all the scheduled task and rerun the  configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar)  concurrently again for each of the new cron expression.

Then call the afterProperties  method of  ScheduledTaskRegistrar  to schedule the task with new cron expressions. 

Here when we destroy the existing triggered job it will shutdown the ScheduledExecutorService also, so it is our responsibility to create new ExecutorService and give to  ScheduledTaskRegistrar .

Here is the complete example: 

Java
 




x
1
41


 
1
@Configuration
2
@EnableScheduling
3
public class SchedulerConfig implements SchedulingConfigurer, DisposableBean {
4

          
5
    protected String cronExpressions;
6
    ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
7
    configDataService // to store the cronexpression in data base so that we can change on the fly when server is running.
8

          
9
    @Override
10
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
11
        cronExpressions = configDataService.getPropertyValue(CRON_EXPRESSIONS);
12
        Stream.of(StringUtils.split(cronExpressions, "|")).forEach(cron -> {
13
            Runnable runnableTask = () -> System.out.println("Task executed at ->" + new Date());
14

          
15
            Trigger trigger = new Trigger() {
16
                @Override
17
                public Date nextExecutionTime(TriggerContext triggerContext) {
18
                    String newCronExpression = configDataService.getPropertyValue(CRON_EXPRESSIONS);
19
                    if (!StringUtils.equalsAnyIgnoreCase(newCronExpression, cronExpressions)) {
20
                        taskRegistrar.setTriggerTasksList(new ArrayList<TriggerTask>());
21
                        configureTasks(taskRegistrar); // calling recursively.
22
                        taskRegistrar.destroy(); // destroys previously scheduled tasks.
23
                        taskRegistrar.setScheduler(executor);
24
                        taskRegistrar.afterPropertiesSet(); // this will schedule the task with new cron changes.
25
                        return null; // return null when the cron changed so the trigger will stop.
26
                    }
27
                    CronTrigger crontrigger = new CronTrigger(cron);
28
                    return crontrigger.nextExecutionTime(triggerContext);
29
                }
30
            };
31
            taskRegistrar.addTriggerTask(runnable, trigger);
32
        });
33
    }
34

          
35
    @Override
36
    public void destroy() throws Exception {
37
        if (executor != null) {
38
            executor.shutdownNow();
39
        }
40
    }
41
}



Always make sure to shut down any executor services that you create.

Please comment here if you see any issues or if you have any suggestions.

Spring Framework Task (computing) Crons Spring Boot Schedule (computer science)

Opinions expressed by DZone contributors are their own.

Related

  • Calling a Client Via Spring @schedule Cron Job
  • Distributed Task Synchronization: Leveraging ShedLock in Spring
  • External Task Client Implementation in Camunda With Spring Boot Application
  • Actuator Enhancements: Spring Framework 6.2 and Spring Boot 3.4

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook