Implementing Dynamic Scheduled Tasks in Spring Boot with Cron and Periodic Triggers
This article demonstrates how to create a Spring Boot demo that runs scheduled tasks, shows how to configure the task with a cron expression, and provides REST endpoints to modify the cron or timer at runtime, including an alternative PeriodicTrigger for flexible intervals.
The author previously wrote about static Spring Boot scheduled tasks using cron expressions defined in configuration files, which cannot be changed at runtime. This guide records how to implement dynamic scheduled tasks that can be updated while the application is running.
Dependencies – only the essential Spring Boot starter dependencies are required:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<optional>true</optional>
</dependency>
<!-- validation for Spring Boot 2.3+ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>Application entry point :
package com.wl.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author wl
*/
@EnableScheduling
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
System.out.println("(*^▽^*)启动成功!!!(〃'▽'〃)");
}
}The application.yml only defines the server port:
server:
port: 8089The task schedule configuration is stored in task-config.ini :
printTime.cron=0/10 * * * * ?Dynamic task implementation (CronTrigger) – a component that reads the cron expression from the properties file and registers a trigger task:
package com.wl.demo.task;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 定时任务
*/
@Data
@Slf4j
@Component
@PropertySource("classpath:/task-config.ini")
public class ScheduleTask implements SchedulingConfigurer {
@Value("${printTime.cron}")
private String cron;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(new Runnable() {
@Override
public void run() {
log.info("Current time: {}", LocalDateTime.now());
}
}, new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
CronTrigger cronTrigger = new CronTrigger(cron);
return cronTrigger.nextExecutionTime(triggerContext);
}
});
}
}A REST controller provides an endpoint to update the cron expression at runtime:
package com.wl.demo.controller;
import com.wl.demo.task.ScheduleTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
private final ScheduleTask scheduleTask;
@Autowired
public TestController(ScheduleTask scheduleTask) {
this.scheduleTask = scheduleTask;
}
@GetMapping("/updateCron")
public String updateCron(String cron) {
log.info("new cron :{}", cron);
scheduleTask.setCron(cron);
return "ok";
}
}Running the project shows the task executing every 10 seconds. After calling /test/updateCron?cron=0/15 * * * * ? , the interval changes to 15 seconds, which is verified by the console output and screenshots.
Alternative trigger – PeriodicTrigger – unlike CronTrigger, it allows arbitrary millisecond intervals (greater than 59 seconds). The modified task class adds a timer field and uses PeriodicTrigger :
package com.wl.demo.task;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
@Data
@Slf4j
@Component
@PropertySource("classpath:/task-config.ini")
public class ScheduleTask implements SchedulingConfigurer {
@Value("${printTime.cron}")
private String cron;
private Long timer = 10000L; // default 10 seconds
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(new Runnable() {
@Override
public void run() {
log.info("Current time: {}", LocalDateTime.now());
}
}, new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
PeriodicTrigger periodicTrigger = new PeriodicTrigger(timer);
return periodicTrigger.nextExecutionTime(triggerContext);
}
});
}
}A second endpoint allows updating the timer value:
@GetMapping("/updateTimer")
public String updateTimer(Long timer) {
log.info("new timer :{}", timer);
scheduleTask.setTimer(timer);
return "ok";
}Testing confirms that changing the timer to 15000 (15 000 ms) makes the task run every 15 seconds, as shown in the screenshots.
Finally, the article ends with a call to join the author’s community and a list of additional resources, but the core technical content is the dynamic scheduling implementation.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.