@EnableScheduling Annotation

The @EnableScheduling annotation need to add in the Spring Boot main class to enable the scheduler tasks in the application.

---Spring Boot Main Class---
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class MainClassApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainClassApplication.class, args);
    }
}

@Scheduled Annotation

@Scheduled annotation is used to configure and schedule tasks for a time period. If you declare @Scheduled annotation on a method, the method type should be void and method should not expect any parameters.

---@Scheduled Example---
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    @Scheduled(initialDelay = 2000, fixedRate = 5000)
    public void firstTask(){
        System.out.println("Task is exicuting");
    }
}

initialDelay = 2000 means the method will wait 2 seconds for the first time then the method will be executed continiously on every 5 seconds as fixedRate = 5000.

fixedRate

fixedRate parameter is used to indicate scheduler for the executing tasks for a time period. Suppose, if we declare fixedRate = 5000 that means the task will be executed on every 5 seconds.

---Scheduling fixedRate  Example---
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    @Scheduled(initialDelay = 2000, fixedRate = 5000)
    public void firstTask(){
        System.out.println("Task is exicuting");
    }
}

initialDelay = 2000 means the method will wait 2 seconds for the first time then the method will be executed continiously on every 5 seconds as fixedRate = 5000.

fixedelay

If you declare fixedelay parameter with fixedRate then it will be used to indicate scheduler to wait for a specific period for the first time only.

If you declare fixedelay parameter without fixedRate then it will be used to indicate scheduler to wait for a specific period for the first time and subsequently task will be executed continiously as per fixedelay time.

Example 1#
Example with parameters fixedelay=2000 and fixedelay=5000. If you provide fixedelay=2000 and fixedelay=5000 then task execution will wait for 2 seconds on the first time and after that task will be executed continiously on every 5 seconds.

Example 2# Example of without fixedRate parameter, such as parameter is fixedelay=5000. If you provide fixedelay=5000 without fixedRate then task execution will wait for 5 seconds on the first time and after that task will be executed continiously on every 5 seconds.

---Scheduling fixedelay  Example---
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    @Scheduled(initialDelay = 2000, fixedRate = 5000)
    public void firstTask(){
        System.out.println("wait 2 seconds on first time, executing on every 5 seconds");
    }

    @Scheduled(initialDelay = 5000)
    public void firstTask(){
        System.out.println("Task is exicuting on every 5 seconds");
    }
}

fixeddelayString

fixeddelayString parameter is used to fetch the value from properties file. If your delay value is dynamic baded on environments or users then you can use it to get the fixed delay value from the properties file.

---Properties File Example---
    spring.task.scheduling.delaytimevalue=2000
    
---Scheduling fixeddelayString  Example---
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    @Scheduled(initialDelayString="${spring.task.scheduling.delaytimevalue}", fixedRate = 5000)
    public void firstTask(){
        System.out.println("Task is exicuting");
    }
}

fixedRateString

fixedRateString parameter is used to fetch the value from properties file. If your fixed rate value is dynamic baded on environments or users then you can use it to get the fixed rate value from the properties file.

---Properties File Example---
    spring.task.scheduling.delaytimevalue=2000
    spring.task.scheduling.ratetimevalue=5000   
    
---Scheduling fixeddelayString  Example---
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    @Scheduled(initialDelayString="${spring.task.scheduling.delaytimevalue}", fixedRateString = "${spring.task.scheduling.ratetimevalue}")
    public void firstTask(){
        System.out.println("Task is exicuting");
    }
}

Spring Scheduling with Time Unit - timeUnit

timeUnit parameter in the Spring scheduling is used to mention the time such as SECONDS, MINUTES, HOUR, DAY etc. If you don't wat to provide milliseconds, you can use timeUnit parameter to set the execution time for a task.

Example of fixedDelay = 5, timeUnit = TimeUnit.SECONDS
If you declare fixedDelay = 5, timeUnit = TimeUnit.SECONDS then the task will be executed on every 5 seconds.

Example of fixedDelay = 5, timeUnit = TimeUnit.MINUTES
If you declare fixedDelay = 5, timeUnit = TimeUnit.MINUTES then the task will be executed on every 5 minutes.

---timeUnit  Example---

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

@Component
public class TaskExample {

    @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS)
    public void firstTask(){
        System.out.println("Task is exicuting on every 5 seconds");
    }

    @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.MINUTES)
    public void firstTask(){
        System.out.println("Task is exicuting on every 5 minutes");
    }
}

initialDelay / One-time Task

The initialDelay attribute provides the functionality to execute a task with some delay time period for one time only. It will never execute again after one time execution.

---initialDelay  Example---

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    @Scheduled(initialDelay = 5000)
    public void firstTask(){
        System.out.println("Task executed one time only after 5 seconds delay");
    }
}

Spring Multiple Task Schedulers

The scheduler attribute is used to execute the task with a particular Thread/Scheduler. If you have multiple tasks and you want to use seperate Thread/Scheduler for the respective task you can declare scheduler attribute inside @Scheduled annotation to assign seperate a Thread for a task.

  1. Need to create beans to create multiple schedulers/threads.
  2. Need to declare scheduler attribute with scheduler name inside @Scheduled annotation.

---Scheduler Beans Example---

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
@EnableScheduling
public class SchedulerConfig {

    @Bean
    @Qualifier("scheduler-1")
    public TaskScheduler taskScheduler1() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setThreadNamePrefix("manual-scheduler-1");
        return scheduler;
    }

    @Bean
    @Qualifier("scheduler-2")
    public TaskScheduler taskScheduler2() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setThreadNamePrefix("manual-scheduler-2");
        return scheduler;
    }

    @Bean
    public TaskScheduler taskScheduler() {

        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setThreadNamePrefix("manual-scheduler-by-type");
        return scheduler;
    }
}
---Spring Scheduling Example---

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    @Scheduled(fixedRate = 5000, scheduler = "scheduler-1")
    public void firstTask(){
        System.out.println(Thread.currentThread().getName());
    }

    @Scheduled(fixedRate = 5000, scheduler = "scheduler-2")
    public void firstTask(){
        System.out.println(Thread.currentThread().getName());
    }

    @Scheduled(fixedRate = 5000)
    public void firstTask(){
        System.out.println(Thread.currentThread().getName());
    }
}

Scheduling Thread Pool Size

In Spring Boot need to add property in properties file to set the Scheduler Thread Pool Size.

If you are not using Spring Boot then need to create beans and you can set the Scheduler Thread Pool Size in the bean method.

---Spring Boot Scheduler Thread Pool Size Example---

spring.task.scheduling.pool.size=10
---Scheduler Thread Pool Size Bean Example---
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
@EnableScheduling
public class SchedulerConfig {

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10);
        scheduler.setThreadNamePrefix("manual-scheduler-by-type");
        return scheduler;
    }
}

@EnableAsync / @Async in Spring Boot Scheduling

Spring Boot Scheduler does not provide the functionality to execute the same task by multiple threads. The @EnableAsync / @Async annotations provides the functionaly of exicuting a task by multiple threads.

  1. Need to declare @EnableAsync annotation with @EnableScheduling annotation in the config or Spring Boot main class.
  2. Need to declare @Async annotation with @Scheduled annotation in the task class.

---Spring Boot Scheduling @EnableAsync Example---
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class SpringBootMainClass {

    public static void main(String[] args) {
		SpringApplication.run(SpringBootMainClass.class, args);
	}
}


---Spring Scheduling with @Async Example---

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.scheduling.annotation.Async;

@Component
public class TaskExample {

    @Scheduled(fixedRate = 5000)
    @Async
    public void firstTask(){
        System.out.println(Thread.currentThread().getName());
    }
}

Spring Boot Scheduling Using CRON Expressions

The CRON Expressions is a string consisting of five fields that describe details of the time to execute a task. Spring Scheduling provides the functionality to execute a task using CRON Expressions. If you use cron expression, no need to use fixedelay or fixedRate to execute a task.

    CRON Expressions fields.
  1. Second
  2. Minute(0-59)
  3. Hour(0-23)
  4. Day Of Month(1-31)
  5. Month(1-12 or Jan-Dec)
  6. Day of Week(0-6 or Sun-Sat)
    CRON Expressions Rules.
  1. A comma(,) to specify a list of allowed values
  2. A hyphen(-) to specify a range of values
  3. A forward slash(/) to specify an interval for a value
    CRON Expressions Values Example.
  1. Every hour(0 0 * * * *)
  2. Every 10 seconds(0/10 * * * * *)
  3. Every hour, between 08:00 AM and 10:59 AM(0 0 8-10 * * *)
  4. Every day at 06:00 AM and 07:00 PM(0 0 6,19 * * *)
  5. Every 30 minutes, between 08:00 AM and 10:59 AM(0 0/30 8-10 * * *)
  6. Every 30 minutes, between 08:00 AM and 10:59 AM, only in August(0 0/30 8-10 * 8 *)
  7. Every day at 09:00 AM, only on Saturday(0 0 9 * * 6)

---Spring Scheduling Cron Expression Example---
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    @Scheduled(cron = "0/10 * * * * *")
    public void cronExample(){
        System.out.println(Thread.currentThread().getName()+" Cron expression every 10 seconds");
    }
}

@yearly or @annually

The @yearly or @annually annotation executes a job once in a year.

  1. @yearly or @annually - The @yearly or @annually annotation executes a job once in a year.
  2. @monthly - The @monthly annotation executes a job once in a month.
  3. @daily - The @daily annotation executes a job once in a day.
  4. @hourly - The @hourly annotation executes a job per hour.

---Spring Scheduling Cron Expression Example---
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskExample {

    ---@yearly Example---
    @Scheduled(cron = "@yearly")
    public void cronExample(){
        System.out.println(Thread.currentThread().getName()+" Cron expression executes once in a year");
    }

    ---@monthly Example---
    @Scheduled(cron = "@monthly")
    public void cronExample(){
        System.out.println(Thread.currentThread().getName()+" Cron expression executes once in a month");
    }

    ---@weekly Example---
    @Scheduled(cron = "@weekly")
    public void cronExample(){
        System.out.println(Thread.currentThread().getName()+" Cron expression executes once in a week");
    }

    ---@daily Example---
    @Scheduled(cron = "@daily")
    public void cronExample(){
        System.out.println(Thread.currentThread().getName()+" Cron expression executes once in a day");
    }

    ---@hourly Example---
    @Scheduled(cron = "@hourly")
    public void cronExample(){
        System.out.println(Thread.currentThread().getName()+" Cron expression executes once per hour");
    }


}