Author Avatar

Pradeep Mishra

0

Share post:

When we have a requirement to run a task/job repeatedly after a particular time interval, we achieve this functionality by implementing Scheduling. To schedule jobs in the spring boot application to run periodically, spring boot provides @EnableScheduling and @Scheduled annotations.

Enabling Scheduling

Scheduling is not enabled by default. Before adding any scheduled jobs we need to enable scheduling explicitly by adding the @EnableScheduling annotation:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class JobschedulingApplication {

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

}

As a best practice, we should move this annotation to a dedicated class under a package that contains the code for our scheduled jobs:

import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
public class SchedulerConfig {

}

The scheduling will now only be activated when we load the SchedulerConfig class into the application, providing better modularization.

When the @EnableScheduling annotation is processed, Spring scans the application packages to find all the Spring Beans decorated with @Scheduled methods and sets up their execution schedule.

Adding Scheduled Jobs

After enabling scheduling, we will add jobs to our application for scheduling. We can turn any method into a Spring bean for scheduling by adding the @Scheduled annotation to it.

The @Scheduled is a method-level annotation applied at runtime to mark the method to be scheduled. It takes one attribute from cronfixedDelay, or fixedRate for specifying the schedule of execution in different formats.

The annotated method needs to fulfill two conditions:

  1. The method should not have a return type and so return void. For methods that have a return type, the returned value is ignored when invoked through the scheduler.
  2. The method should not accept any input parameters.

In this blog, we will only discuss and look briefly into the cron expression for scheduling a job.

Using Cron Expressions to Define the Interval

Cron Expressions are the most widely used approach to achieve scheduling. Cron Expressions are very popular in Unix/Linux OS for scheduling. Spring framework also incorporates the same concept internally. Spring Framework offers us an API where we can utilize Cron expression to get the task scheduled as shown in this example:

package com.dev.springboot.scheduling;

import java.util.Date;

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

@Component
public class SchedulerServiceThree {

	@Scheduled(cron = "15 * * * * *")
	public void scheduledMethod() {
		System.out.println("Hello cron Scheduler Three :" +new Date());
	}
}

Here we have specified the interval using a cron expression. Specifically, the above cron expression indicates executing the task at every minute 15th second.

How to write a Cron Expression?

A cron expression is a string consisting of six or seven subexpressions (fields) that describe individual details of the schedule. These fields, separated by white space, can contain any allowed values with various combinations of the allowed characters for that field. The below picture shows the fields in the expected order and allowed values with characters.

As per the Spring Framework’s documentation, the allowed values for the field ‘day of the week’ are 0-7. Here ‘0’ or ‘7’ both represent ‘Sunday’. Hence, the listings show a clear mapping of days with numbers.

The previous versions and the latest Spring 6.0 supports six fields in the cron expression: second, minute, hour, day of month, month and day of week. 

How To Write a Cron Expression?

There are 6 Asterisks(* * * * * *) by default in a cron expression as shown below. Further, each asterisk has some meaning as they denote a value. These values can be assigned as Second, Minute, Hour, Day, Month, and Weekday respectively in sequence.
Possible values at the proper place are also given below.

 ┌───────────── second (0-59)
 │ ┌───────────── minute (0 - 59)
 │ │ ┌───────────── hour (0 - 23)
 │ │ │ ┌───────────── day of the month (1 - 31)
 │ │ │ │ ┌───────────── month (1 - 12) (or JAN-DEC)
 │ │ │ │ │ ┌───────────── day of the week (0 - 7)
 │ │ │ │ │ │          (or MON-SUN -- 0 or 7 is Sunday)
 │ │ │ │ │ │
 * * * * * *
  • A Cron Expression can accept symbols : *  –   ,   /   ?
  • Comma denotes possible values
    For example, the expression “0 0 4,14 * * *” denotes ‘4:00:00AM and 2:00:00 PM’ every day.
  • Dash (-) denotes a range, which means, considering all possible values between the range. Ranges of numbers are expressed by two numbers separated with a hyphen. The specified range is inclusive.
    For example, the expression ”0 0 2-4 * * *” just denotes ‘execute given task every day 2:00:00AM, 3:00:00AM, and 4:00:00AM’.
  • Asterisk(*) denotes any/every/all value
    For example, the expression “0 0 * * * *” denotes ‘the top of every hour of every day’ or in simple terms ‘hourly’.
  • Forward slash(/) denotes a period of time
    For example, the expression “0 0/30 2-4 * * *” denotes ‘2:00, 2:30, 3:00, 3:30, 4:00 and 4:30 AM every day’.
  • Question mark(?) denotes any value like *, but it can be used for the ‘day of the month’ or ‘day of the week’ fields instead of an asterisk.
  • English names can also be used for the month and the day-of-week fields. Use the first three letters of the particular day of the week or month (case does not matter). While writing a Spring Scheduling Cron Expression, it is advisable to use English names for the ‘day-of-week’ and ‘months’ instead of numbers, as they are self-explanatory and also eliminate the chances of making mistakes.
    For example, 11 = NOV and 5 = FRI

New Features as Corn Expression Improvements in Spring 5.3

These improvements are available in Spring Boot as well since Spring Boot 2.4.

Macros

Spring now supports some macros, which represent commonly used sequences in order to improve readability. Even we can use these macros rather than writing the six-digit values. They will not only save you time but also eliminate the chances of making mistakes. Below is the list of macros that we can use in our code in case of Spring 5.3 or later versions.

1) For Once a Year:    @yearly or @annually  in place of  “0 0 0 1 1 *”

2) For Once a Month: @monthly in place of  “0 0 0 1 * *”

3) For Once a Week:   @weekly in place of  “0 0 0 * * 0”

4) For Once a Day:     @daily or @midnight in place of  “0 0 0 * * *”

5) For Once an Hour: @hourly in place of  “0 0 * * * *”

Last Days (L)

The character ‘L’ stands for last. We can use this character in the ‘day of month’ and ‘day of week’ fields. Let’s take some examples:

Cron ExpressionMeaning
0 0 0 L * *Last day of the month at midnight
0 0 0 L-2 * *Second-to-last day of the month at midnight
0 0 0 * * 4LLast Thursday of the month at midnight
0 0 0 * * MONLLast Monday of the month at midnight

Weekdays (W)

The character ‘W’ stands for Weekdays. We can use this character in the ‘day of month’ field. Let’s see some examples:

Cron ExpressionMeaning
0 0 0 1W * *First weekday of the month at midnight
0 0 0 LW * *Last weekday of the month at midnight

Day of the Week in the Month (#)

The character ‘#’ is applicable to the ‘day of week’ only. The ‘day of week’ field can be ‘d#n’ or ‘DDD#n’, which stands for ‘the n-th day of week d or DDD in the month’. Let’s see some examples:

Cron ExpressionMeaning
0 0 0 ? * 5#3The third Friday in the month at midnight
0 0 0 ? * SUN#1The first Sunday in the month at midnight

How to Configure Scheduler with Time zone

By default, Spring will use the server’s local time zone for the cron expression. However, we can use the zone attribute to change this timezone:

@Scheduled(cron = "0 15 10 15 * ?", zone = "Europe/Paris")

With this configuration, Spring will schedule the annotated method to run at 10:15 AM on the 15th day of every month in Paris time. This zone element is available from version 4.0.

As described in the documentationzone accepts IDs that are valid for TimeZone.getTimeZone(String).
In TimeZone documentation you will find the following for such method:

the ID for a TimeZone, either an abbreviation such as “PST”, a full name such as “America/Los_Angeles”, or a custom ID such as “GMT-8:00”. Note that the support of abbreviations is for JDK 1.1.x compatibility only and full names should be used.

Meaning that full names should be used instead of abbreviations as it will also help in many zones from daylight saving (DST) changes. For example, instead of using EST use “America/New_York” as EST gets converted into EDT after DST implementation.

Conclusion

We have discussed the concepts of Spring Scheduling Cron Expression at length, including ample amounts of examples in this article. Moreover, we have also discussed improvements in Cron Expressions in Spring 5.3. Please provide your comments in the comment box if any.

Accessing Data with JPA
Build a module with its dependencies in a multi-module Maven project

Leave a Reply