In Spring Boot, creating a scheduler is a straightforward process thanks to the @Scheduled annotation. A scheduler is used to execute a task at a specific time or on a regular interval. Spring provides built-in support for scheduling tasks with the @Scheduled
annotation, and it also allows you to define cron expressions for more complex scheduling patterns.
Here’s a step-by-step guide on how to create a scheduler in Spring Boot.
Steps to Create a Scheduler in Spring Boot
1. Enable Scheduling in Spring Boot
To start, you need to enable scheduling in your Spring Boot application by adding the @EnableScheduling
annotation to your main application class or any configuration class.
1 2 3 4 5 6 7 8 9 10 11 12 |
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling // Enables scheduling in the Spring application public class SchedulerApplication { public static void main(String[] args) { SpringApplication.run(SchedulerApplication.class, args); } } |
2. Define Scheduled Tasks
Next, create a method inside a Spring component (such as a service or a controller) and annotate it with @Scheduled
. Spring provides several ways to define schedules:
- Fixed Rate: The task will be executed at regular intervals, regardless of the previous task’s completion.
- Fixed Delay: The task will be executed with a delay after the previous task is completed.
- Cron Expressions: You can define a specific schedule using cron expressions.
Example: Simple Scheduled Task with @Scheduled
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class MyScheduledTask { // Task to run at a fixed interval of 5 seconds @Scheduled(fixedRate = 5000) public void executeTaskAtFixedRate() { log.info("Task executed at fixed rate - " + System.currentTimeMillis()); } // Task to run with a fixed delay of 3 seconds after the previous task finishes @Scheduled(fixedDelay = 3000) public void executeTaskWithFixedDelay() { log.info("Task executed with fixed delay - " + System.currentTimeMillis()); } // Task to run at specific times using a cron expression (Every day at 9 AM) @Scheduled(cron = "0 0 9 * * ?") public void executeTaskWithCronExpression() { log.info("Task executed with cron expression at 9 AM - " + System.currentTimeMillis()); } } |
3. Configuring Different Scheduling Patterns
Option 1: Fixed Rate Scheduling
With fixedRate
, the task is executed at a constant interval, regardless of whether the previous task has completed or not.
1 2 3 4 |
@Scheduled(fixedRate = 5000) // Runs every 5 seconds public void fixedRateTask() { log.info("Fixed Rate Task executed"); } |
fixedRate
specifies how often the task should be invoked, in milliseconds. In this example, the task will be executed every 5 seconds.
Option 2: Fixed Delay Scheduling
With fixedDelay
, the task is executed after a delay following the completion of the previous execution.
1 2 3 4 |
@Scheduled(fixedDelay = 3000) // Runs 3 seconds after the previous execution is finished public void fixedDelayTask() { log.info("Fixed Delay Task executed"); } |
fixedDelay
starts the next execution 3 seconds after the previous execution is completed.
Option 3: Cron Expression Scheduling
Cron expressions give you more flexibility by allowing you to specify exactly when a task should run, such as every Monday at 10 AM or every day at midnight.
1 2 3 4 |
@Scheduled(cron = "0 0 9 * * ?") // Runs every day at 9 AM public void cronExpressionTask() { log.info("Cron Expression Task executed"); } |
- Cron expression syntax:
0 0 9 * * ?
means:0
: Second (0th second of the minute).0
: Minute (0th minute of the hour).9
: Hour (9 AM).*
: Every day of the month.*
: Every month.?
: Any day of the week.
You can use various online cron expression generators to help you create custom cron patterns. For example:
- Every minute:
"0 * * * * ?"
- Every Monday at 8 AM:
"0 0 8 * * MON"
4. Parameterize Scheduling Values Using application.properties
You can define the scheduling interval or cron expressions in your application.properties
or application.yml
to make them configurable.
1 2 3 |
# application.properties scheduler.fixedRate=5000 scheduler.cron=0 0 10 * * ? |
And then reference them in your @Scheduled
annotation like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class ConfigurableScheduledTask { @Value("${scheduler.fixedRate}") private long fixedRate; @Value("${scheduler.cron}") private String cronExpression; @Scheduled(fixedRateString = "${scheduler.fixedRate}") public void executeFixedRateTask() { log.info("Task executed at fixed rate - " + fixedRate); } @Scheduled(cron = "${scheduler.cron}") public void executeCronTask() { log.info("Task executed with cron expression - " + cronExpression); } } |
5. Scheduling Asynchronous Tasks
If you want your scheduled tasks to run asynchronously (in separate threads), you need to enable asynchronous execution by adding the @EnableAsync
annotation to your application and use the @Async
annotation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; @Component public class AsyncScheduledTask { @Async @Scheduled(fixedRate = 5000) public void executeAsyncTask() throws InterruptedException { log.info("Async task started: " + Thread.currentThread().getName()); TimeUnit.SECONDS.sleep(2); log.info("Async task completed: " + Thread.currentThread().getName()); } } |
By using @Async
, the task will run in a separate thread, so it won’t block the main thread.
6. Scheduling with Spring’s TaskScheduler
For more control over scheduling tasks, you can use Spring’s TaskScheduler
interface instead of the @Scheduled
annotation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; @Configuration public class SchedulerConfig { // Define a TaskScheduler bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(10); // Set pool size for concurrent tasks scheduler.setThreadNamePrefix("MyScheduler-"); scheduler.initialize(); return scheduler; } } |
Common Use Cases for Spring Boot Scheduler
- Periodic Data Cleanup: Automatically clean up stale data from your database at a regular interval.
- Database Backups: Schedule regular database backup operations.
- Notification Emails: Send out automated email notifications at specific times (e.g., reminders, marketing campaigns).
- Data Synchronization: Periodically sync data between services or external systems.
- Status Monitoring: Run scheduled health checks or status reports.
Important Considerations
- Thread Management: By default, all scheduled tasks are executed by a single-threaded task executor. If you need parallel execution, configure a thread pool using
ThreadPoolTaskScheduler
. - Exception Handling: If an exception is thrown in a scheduled task, the task will stop running. Make sure to handle exceptions inside your tasks.
- Time Zones: If your application is deployed in different time zones, consider specifying the time zone in cron expressions using the
zone
attribute.
1234@Scheduled(cron = "0 0 10 * * ?", zone = "America/New_York")public void taskWithTimezone() {log.info("Task with timezone executed");}
Summary
In Spring Boot, creating a scheduler is simple with the @Scheduled
annotation. You can schedule tasks at fixed intervals, after delays, or with complex schedules using cron expressions. The configuration is flexible, and you can even parameterize schedules in properties files. You also have the option to run tasks asynchronously or manage them via Spring’s TaskScheduler
for more control.
Schedulers are powerful tools for automating tasks, improving productivity, and maintaining your application’s stability in production environments.