Scheduling Task In Spring Boot

In this article we will build a simple spring boot application where we will schedule a task that gets triggered automatically at a certain interval. Scheduling is an important concept when we want to accomplish a certain task at a certain time of day, or periodically at a certain interval for example, sending e-mails to employee every end of the month.

Overview

Spring has provided @Scheduled annotation along with some trigger parameters to achieve scheduling. You have to annotate a method with @Scheduled annotation and write your scheduling logic.

Criteria for using @Scheduled annotation

  • Scheduling method should have a void return type.
  • Scheduling method should not accept any arguments.

Enable Scheduling

Before start using scheduling, we have to enable it by using @EnableScheduling either in Spring Boot Application class or Configuration classses.

@EnableScheduling
@SpringBootApplication
public class SpringBootSchedulingDemoApplication {
}

@Scheduled annotation triggering parameters

You can use the properties fixedRate/fixedDelay/initialDelay/cron to provide the triggering information with @Scheduled annotations. They are discussed with sample example below.

we will show the execution time of each scheduled task in following data format.

private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
Schedule a task with Fixed Rate

Use fixedRate if you want to schedule a task to be executed at a fixed interval. Such scheduled task is invoked at the specified interval even if the previous invoked task is not finished.

@Scheduled(fixedRate = 2000)
public void scheduleTaskWithFixedRate() {
   System.out.println("Scheduled fixedRate Task :: Execution Time :: "+ formatter.format(LocalDateTime.now()) );
}

If you don’t want to hard-code the fixedRate value, fixedRateString option is given. Just write the key-value pair in application.properties and read the key using spring expression as follows.

@Scheduled(fixedRateString = "${fixedrate.in.milliseconds}") 
Schedule a task with Fixed Delay

fixedDelay task is executed between the completion of the last invocation and the start of the next invocation. Well, that means if you have scheduled a fixedDelay task for 3 seconds and your task took 4 seconds to execute its complete logic, then next invocation  will be triggered after 7 seconds. So, the fixedDelay parameter counts the delay after the completion of the last invocation.

@Scheduled(fixedDelay = 2000)
public void scheduleTaskWithFixedDelay() {
     System.out.println("Scheduled fixedDelay Task :: Execution Time::" + formatter.format(LocalDateTime.now()));
       try {
	    TimeUnit.SECONDS.sleep(5);
       }catch (InterruptedException ex) {
	   System.out.println("Error Occured" + ex);
	   throw new IllegalStateException(ex);
	}
}

fixedDelayString is provided if you dont want to hard-code the values.

@Scheduled(fixedDelayString= "${fixedDelayString.in.milliseconds}") 
Schedule a task with Initial Delay

initialDelay parameter can be used along with fixedRate or fixedDelay to delay the first execution of the task with the specified number of milliseconds.

 @Scheduled(fixedRate = 2000, initialDelay = 5000)
  public void scheduleTaskWithInitialDelay() {
    System.out.println("Scheduled fixedRate Task with initialDelay:: Execution Time::" + formatter.format(LocalDateTime.now()));
  }
@Scheduled(fixedRateString = "${fixedrate.in.milliseconds=2000}", initialDelayString = "${initialDelay.in.milliseconds}")
Schedule a task with Cron Expression

If you want to have more control over scheduling of a task, then you can make use of cron property provided by @Scheduled annotation. As Oracle Documentation states

A cron expression is a string consisting of six or seven sub-expressions (fields) that describe individual details of the schedule.

@Scheduled(cron = "[Seconds] [Minutes] [Hours] [Day of month] [Month] [Day of week] [Year]")

Each sub-expressions/fields, separated by white space, can contain any of the allowed values with various combinations of the allowed characters for that field. Refer the following table given in the Oracle Site for reference.

Allowed Fields and Values in Cron Expressions

Cron Expression Examples

Example : Fire at 10:15 AM every day
@Scheduled(cron = "0 15 10 * * ? *")
public void scheduleTaskWithCronExpression() {
  System.out.println("Scheduled Cron Task :: Execution Time ::" + formatter.format(LocalDateTime.now()));
}

If you wish not to hard-code the expression, you can configure the value in application.properties file and read the key as below.

@Scheduled(cron= "${cron.expression}")

Full Example :

Create Spring Boot Project

Create spring boot application from Spring Initializr. Provide the project related meta-data and dependencies as shown below. Click on Generate Project, a zip file will be downloaded. Extract it in your preferred location and import in the your preferred IDE. Here we are using Eclipse Oxygen.

Project Structure

Following is the structure in the project explorer of eclipse IDE that we are going to develop.

Project Dependencies : pom.xml
Spring Boot Application class
Scheduling Task with @Scheduled Annotation
application.properties : Don’t hard-code your values in code

If you don’t want to hard-code the triggering parameters in @Scheduled annotation then write those values in application.properties and read it with the help of Spring Expression as mentioned earlier.

[su_box title=”application.properties” box_color=”#faf62b” title_color=”#151111″]

fixedrate.in.milliseconds=2000
fixedDelay.in.milliseconds=2000
initialDelay.in.milliseconds=5000
cron.expression=0 15 10 * * ? *

[/su_box]

Run the above application and see the execution time of each scheduled task. I hope this article has helped you feel confident to use @Scheduled annotation as per your need. Happy Coding…!!

References

https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm

6 Comments

Leave a Reply