This post explores the integration of a REST API to control a scheduler in a Spring Boot application. The Spring Boot application is designed to offer two REST APIs, enabling the initiation and cessation of the scheduler. Initiating the scheduler is achieved by invoking the start REST API, launching a sample Spring Boot scheduler that persists until the stop API is called. The stop REST API effectively halts the scheduler. This section delves into the management of the Spring Boot Scheduler through REST web services. The implementation in this Spring Boot example involves utilizing scheduler annotations such as @EnableScheduling and @Scheduled.

Step 1 – Create Spring Boot Application

The creation of a scheduler in a Spring Boot application can be seamlessly achieved using the default Spring Boot setup, requiring no additional dependencies for schedulers. In this example, a REST web service is employed to handle the scheduler. To establish a RESTful web service, the inclusion of the spring-web dependency is essential. The REST web service is hosted on the default Tomcat server. Including the spring-web dependency in the project ensures the automatic download of all necessary Tomcat server and RESTful web service dependency JARs, streamlining the setup process.

Step 2 – Create pom.xml file with dependencies

The pom.xml file serves as the configuration hub for essential JAR file dependencies. In this instance, an integral addition to the dependencies is the inclusion of the Spring Web dependency, pivotal for implementing RESTful web services. Below is a sample pom.xml file illustrating this configuration:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.0.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.test</groupId>
	<artifactId>SpringBootSchedulerRestApi</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringBootSchedulerRestApi</name>
	<description>Database project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Step 3 – Scheduler Configurations

Enabling and executing a scheduler in Spring Boot involves three essential steps. Firstly, the @EnableScheduling annotation should be incorporated into the main class or any configuration class. This annotation directs Spring Boot to activate schedulers within the application. Secondly, the @Configuration annotation must be applied to the class responsible for configuring the scheduler tasks. The @Scheduled annotation is then utilized to define the scheduling parameters.

Various scheduler options, including FixedRate, Fixed Delay, Cron, among others, offer flexibility. In this example, the FixedRate scheduler is employed. The @Scheduled annotation configures the scheduler type as an argument.

The subsequent example showcases a Spring Boot Scheduler that outputs the current time every 5 seconds. This is achieved by defining a method annotated with @Scheduled to execute at the specified interval. If the scheduler is activated, the current time will be printed every 5 seconds.

SchedulerConfig.java

package com.test;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

@Configuration
@EnableScheduling
public class SchedulerConfig {
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");

	@Scheduled(fixedRate = 5000)
	public void schedule() throws Exception {
		System.out.println("Scheduler " + sdf.format(Calendar.getInstance().getTime()) + "\n");
	}
}

Step 4 – Rest Controller Class to Start and Stop Scheduler

The subsequent REST controller class comprises methods designed for initiating and terminating the scheduler through two distinct APIs. The runtime activation and deactivation of the scheduler are facilitated by utilizing the ScheduledAnnotationBeanPostProcessor Spring Boot class. The ScheduledAnnotationBeanPostProcessor is instrumental in enabling or disabling the Spring Boot scheduler and is employed by the RestController class.

To commence a scheduler, utilize the postProcessAfterInitialization method, requiring the Scheduler configuration class and a designated string name as parameters. Conversely, to cease a scheduler, employ the postProcessBeforeDestruction method, necessitating parameters for both the scheduler configuration and the scheduler name.

Contained within the TestController class are RESTful web service implementations for the two APIs dedicated to initiating and halting the Spring Boot scheduler.

TestController.java

package com.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

	@Autowired
	private ScheduledAnnotationBeanPostProcessor postProcessor;

	@Autowired
	private SchedulerConfig schedulerConfig;

	@GetMapping(value = "/start")
	public String start() {
		postProcessor.postProcessAfterInitialization(schedulerConfig, "Task");
		return "STARTED";
	}

	@GetMapping(value = "/stop")
	public String stop() {
		postProcessor.postProcessBeforeDestruction(schedulerConfig, "Task");
		return "STOPPED";
	}

}

Step 5 – Default Main Method

The default main method of the main class is utilized without any alterations. The following presents the default Spring Boot main class:

SpringBootSchedulerRestApiApplication.java

package com.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootSchedulerRestApiApplication {

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

}

In this default configuration, the SpringApplication.run method initiates the Spring Boot application. The @SpringBootApplication annotation encapsulates various annotations, including @EnableScheduling, to facilitate automatic configuration.

Step 6 – Run the Application

The Spring Boot application is now ready for use. Initiate the Spring Boot program, and upon launch, the scheduler logs will be automatically displayed in the console log. The scheduler log will be printed every 5 seconds as configured. The ensuing Spring Boot console log exemplifies how the logs will be presented, showcasing a 5-second interval between two consecutive scheduler logs.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.3)

2023-03-09 16:10:25.958  INFO 6464 --- [           main] .t.SpringBootSchedulerRestApiApplication : Starting SpringBootSchedulerRestApiApplication using Java 17.0.4 on DESKTOP-DMI8H0A with PID 6464 (C:\workspace\SpringBootSchedulerRestApi\target\classes started by Admin in C:\workspace\SpringBootSchedulerRestApi)
2023-03-09 16:10:25.961  INFO 6464 --- [           main] .t.SpringBootSchedulerRestApiApplication : No active profile set, falling back to 1 default profile: "default"
2023-03-09 16:10:27.107  INFO 6464 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-03-09 16:10:27.126  INFO 6464 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-03-09 16:10:27.126  INFO 6464 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.65]
2023-03-09 16:10:27.278  INFO 6464 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-03-09 16:10:27.279  INFO 6464 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1246 ms
2023-03-09 16:10:27.782  INFO 6464 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-03-09 16:10:27.815  INFO 6464 --- [           main] .t.SpringBootSchedulerRestApiApplication : Started SpringBootSchedulerRestApiApplication in 2.356 seconds (JVM running for 3.903)
Scheduler 2023-03-09 16:10:27.820

Scheduler 2023-03-09 16:10:32.795

Scheduler 2023-03-09 16:10:37.795

Scheduler 2023-03-09 16:10:42.796

Scheduler 2023-03-09 16:10:47.795

Scheduler 2023-03-09 16:10:52.796

How to Stop the Spring Boot Scheduler by Runtime

An API is available in the Spring Boot REST web service to stop the scheduler. To cease the Spring Boot scheduler, make a stop API call at http://localhost:8080/stop. Following the execution of the stop API call, the scheduler logs will cease to appear in the console window.

How to Start the Spring Boot Scheduler by Runtime

Start the scheduler through a distinct API in the REST controller by making a call to the start API. Upon invoking the start API call, the scheduler logs will commence printing in the console window at five-second intervals. Invoke the start apiĀ  http://localhost:8080/start to run the scheduler.

Leave a Reply