In this tutorial we will walk through how to implement and define crob jobs with a schedule behind of it in Spring Framework. Generally, in software architectures we want to have some background jobs to do some processing, aggregating or even just fetching some data
and streaming them. Instead of implementing separate cron jobs and managing them as a separate application we can create and maintain cron jobs in same spring application with using @Scheduled annotation. Generally, all the scheduled tasks will run on the same thread which means when current task is being processed others will get blocked and has to wait current thread to finish. However, this can be configured by implementing our own ThreadPoolTaskExecutor to assign a thread pool. So that each task will run asyncrohonously.
First, we have to enable scheduling globally from Spring context to our @Configuration class by adding @EnableScheduling annotation.
Now before diving in there are some properties belongs to @Scheduled annotation that we need to know.
This property is for making a task to wait for its first execution after application has started. For example; if initialDelay is set to 5000 then the task will wait 5 seconds after the spring application started.
This property is for making the task to wait N milliseconds after the previous task has finished. For example; if fixedDelay is set to 5000 then Thread_2 will start 5 seconds after the end of the execution of Thread_1.
This property is for making the task to run at every N millisecond without wating the previous task to finish. For example; if fixedRate is set to 5000 then Thread_2 will start 5 seconds after Thread_1's start time without waiting it to be finished. One thing to note here is since the current running thread won't wait other ones which will cause all threads allocated in the thread pool. And you might also get StackOverflowException if you run out of memory while running all the threads.
This is the cron expression to define running interval for a task.
1. Schedule a Task with FixedDelay
The first the task will start 5 seconds after spring application started and each of the following task will start 3 seconds after the previous one finished.
2. Schedule a Task with FixedRate
The first the task will start 5 seconds after spring application started and each of the following task will start right after the previous one has finished.
3. Schedule a Task with Cron Expression
First thing to note here is Spring Cron is not same as Unix Cron format which consists of 5 fields to define an expression. Where a Spring Cron expression has 6 fields including time unit of second in addition to other 5 fields.
Here is the description from CronSequenceGenerator in Spring;
The pattern is a list of six single space-separated fields: representing second, minute, hour, day, month, weekday. Month and weekday names can be given as the first three letters of the English names.
As an example we will define a cron job which will run at 5th minute at each hour from Monday to Friday. So, the time of running in an hours will be 05, 15, 25, 35, 45, 55 and so on.
Before finalizing this tutorial there is one thing to mention which is about configuring a thread pool to make these tasks running on multiple threads concurrently. You might notice that all the tasks we ran was running on one thread with name scheduling-1. Generally, in sofware systems we had more than one job to make them running without blocking each other. So, to make threads running concunrently we will create our own ThreadPoolTaskScheduler. Here is a quote from the documentation of @EnableScheduling
Now we will create a task executor with a thread pool size of 5 inside a configuration class
We can clearly see that all the tasks are distributed and scheduled on different threads from the thread pool we initialized.