This guide walks you through the steps for scheduling tasks with Spring.

What you’ll build

You’ll build an application that prints out the current time every five seconds using Spring’s @Scheduled annotation.

What you’ll need

  • About 15 minutes

  • A favorite text editor or IDE

  • JDK 1.8 or later

  • Gradle 2.3+ or Maven 3.0+

  • You can also import the code straight into your IDE:

    • Spring Tool Suite (STS)

    • IntelliJ IDEA

How to complete this guide

Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.

To start from scratch, move on to Build with Gradle.

To skip the basics, do the following:

  • Download and unzip the source repository for this guide, or clone it using Git: git clone https://github.com/spring-guides/gs-scheduling-tasks.git

  • cd into gs-scheduling-tasks/initial

  • Jump ahead to Create a scheduled task.

When you’re finished, you can check your results against the code in gs-scheduling-tasks/complete.

Build with Gradle

Build with Maven

Build with your IDE

Create a scheduled task

Now that you’ve set up your project, you can create a scheduled task.

src/main/java/hello/ScheduledTasks.java

package hello;import java.text.SimpleDateFormat;import java.util.Date;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;@Componentpublic class ScheduledTasks {    private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");    @Scheduled(fixedRate = 5000)    public void reportCurrentTime() {        log.info("The time is now {}", dateFormat.format(new Date()));    }}

The Scheduled annotation defines when a particular method runs. NOTE: This example uses fixedRate, which specifies the interval between method invocations measured from the start time of each invocation. There are other options, like fixedDelay, which specifies the interval between invocations measured from the completion of the task. You can also use @Scheduled(cron=". . .") expressions for more sophisticated task scheduling.

Enable Scheduling

Although scheduled tasks can be embedded in web apps and WAR files, the simpler approach demonstrated below creates a standalone application. You package everything in a single, executable JAR file, driven by a good old Java main() method.

src/main/java/hello/Application.java

package hello;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication@EnableSchedulingpublic class Application {    public static void main(String[] args) throws Exception {        SpringApplication.run(Application.class);    }}

@SpringBootApplication is a convenience annotation that adds all of the following:

  • @Configuration tags the class as a source of bean definitions for the application context.

  • @EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.

  • Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.

  • @ComponentScan tells Spring to look for other components, configurations, and services in the hello package, allowing it to find the controllers.

The main() method uses Spring Boot’s SpringApplication.run() method to launch an application. Did you notice that there wasn’t a single line of XML? No web.xml file either. This web application is 100% pure Java and you didn’t have to deal with configuring any plumbing or infrastructure.

@EnableScheduling ensures that a background task executor is created. Without it, nothing gets scheduled.

Build an executable JAR

You can run the application from the command line with Gradle or Maven. Or you can build a single executable JAR file that contains all the necessary dependencies, classes, and resources, and run that. This makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.

If you are using Gradle, you can run the application using ./gradlew bootRun. Or you can build the JAR file using ./gradlew build. Then you can run the JAR file:

java -jar build/libs/gs-scheduling-tasks-0.1.0.jar

If you are using Maven, you can run the application using ./mvnw spring-boot:run. Or you can build the JAR file with ./mvnw clean package. Then you can run the JAR file:

java -jar target/gs-scheduling-tasks-0.1.0.jar
The procedure above will create a runnable JAR. You can also opt to build a classic WAR file instead.

Logging output is displayed and you can see from the logs that it is on a background thread. You should see your scheduled task fire every 5 seconds:

[...]2016-08-25 13:10:00.143  INFO 31565 --- [pool-1-thread-1] hello.ScheduledTasks : The time is now 13:10:002016-08-25 13:10:05.143  INFO 31565 --- [pool-1-thread-1] hello.ScheduledTasks : The time is now 13:10:052016-08-25 13:10:10.143  INFO 31565 --- [pool-1-thread-1] hello.ScheduledTasks : The time is now 13:10:102016-08-25 13:10:15.143  INFO 31565 --- [pool-1-thread-1] hello.ScheduledTasks : The time is now 13:10:15

Summary

Congratulations! You created an application with a scheduled task. Heck, the actual code was shorter than the build file! This technique works in any type of application.

Want to write a new guide or contribute to an existing one? Check out our contribution guidelines.

All guides are released with an ASLv2 license for the code, and an Attribution, NoDerivatives creative commons license for the writing.