Backend Development 10 min read

Implementing Dynamic Scheduled Tasks in Spring Boot

This article demonstrates how to create and modify Spring Boot scheduled tasks at runtime by using configurable cron expressions or interval timers, providing full code examples for Maven dependencies, the application entry point, dynamic task configuration, and REST endpoints for updating the schedule.

Top Architect
Top Architect
Top Architect
Implementing Dynamic Scheduled Tasks in Spring Boot

Previously, static scheduled tasks in Spring Boot required cron expressions defined in configuration files, which could not be changed while the application was running. This tutorial shows how to implement dynamic scheduling that can be updated at runtime.

Dependencies

<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>
    <!-- spring-boot 2.3+ needs explicit validation dependency -->
    <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: 8089

The cron expression is stored in task-config.ini :

printTime.cron=0/10 * * * * ?

Dynamic task implementation

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;

/**
 * 定时任务
 * @author wl
 */
@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) {
        // 动态使用 cron 表达式设置循环间隔
        taskRegistrar.addTriggerTask(new Runnable() {
            @Override
            public void run() {
                log.info("Current time: {}", LocalDateTime.now());
            }
        }, new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                // 使用 CronTrigger,可在运行时修改 cron 表达式
                CronTrigger cronTrigger = new CronTrigger(cron);
                return cronTrigger.nextExecutionTime(triggerContext);
            }
        });
    }
}

A REST controller is provided 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";
    }
}

After starting the application, the task runs every 10 seconds. By calling /test/updateCron?cron=0/15 * * * * ? , the interval changes to 15 seconds, which can be verified in the console output.

Besides the CronTrigger , a PeriodicTrigger can be used for intervals that exceed the 59‑second limitation of cron expressions. The following version adds a timer field (in milliseconds) and switches to 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.CronTrigger;
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(() -> log.info("Current time: {}", LocalDateTime.now()), triggerContext -> {
            // Use PeriodicTrigger for arbitrary millisecond intervals
            PeriodicTrigger periodicTrigger = new PeriodicTrigger(timer);
            return periodicTrigger.nextExecutionTime(triggerContext);
        });
    }
}

The controller is extended with an endpoint to update the timer:

@GetMapping("/updateTimer")
public String updateTimer(Long timer) {
    log.info("new timer :{}", timer);
    scheduleTask.setTimer(timer);
    return "ok";
}

Testing shows the task interval changes according to the supplied timer value.

In summary, the article provides a complete, runnable Spring Boot demo that enables dynamic modification of scheduled tasks using either cron expressions or a millisecond‑based periodic trigger, and exposes simple REST APIs for on‑the‑fly updates.

BackendJavaSpringBootCronRESTDynamicScheduling
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.