Spring Boot Task Scheduling

2.1.12 Timing Tasks

The Spring framework comes with task scheduling capabilities that are like a lightweight Quartz and are easy to use without relying on other JAR packages.

Simply add @EnableScheduling to the project master startup class to turn on task scheduling

public class LearnApplication {
    public static void main(String[] args) {
        SpringApplication.run(LearnApplication.class, args);
} Simple Timing Tasks
public class TestTask {

    @Scheduled(cron = "0/10 * * * * *")
    public void testTask1() {
        System.out.println("[Task 1) Test Timing Task" + LocalDateTime.now());


As mentioned above, configuring a simple timed task can use it simply by adding the @Shceduled annotation to the scheduling method. Asynchronous Timed Tasks
// Turn on Asynchronous Support
public class TestTask {

    @Scheduled(cron = "0/10 * * * * *")
    // Method uses asynchronous execution, creating one thread per task to execute the task
    public void testTask1() {
        System.out.println("[Task 1) Test Timing Task" + LocalDateTime.now() + "   " + Thread.currentThread().getName());
        for (int i = 0; i < 20; i++) {
            try {
            } catch (InterruptedException e) {

            System.out.println("[Task 1) Hibernate" + (i + 1) + "Seconds test timer task" + LocalDateTime.now() + "   " + Thread.currentThread().getName());



Often in our project scheduling tasks, there are scenarios where the next scheduled task needs to be executed before the current task has been completed, in which case the scheduled task needs to be executed asynchronously.

@EnableAsync turns on Asynchronous Support

@Async tag task executes asynchronously (next task will start at the next configuration time, without waiting for the current task to finish executing) Dynamic Timing Tasks

When we write a timed task, the process is roughly coding - > configuring the execution cycle - > starting the service.

The current execution cycle we configure is 8 a.m. every day, when we have a day and need to change at 8 p.m. every day, our operation flow is: modify the execution cycle - > new version packaging - > stop - > start the new version of the service.The whole process line has many steps and uncontrollable factors.

So how do we not stop updating our execution cycle?

So let's simulate storing the cron expression in MySQL.

1) Define cron-related service s

// Expression-related interfaces
public interface SwitchService {

     * Get the latest cron expression
     * @param taskId Task ID
     * @return Latest cron expression
    String getCron(String taskId);

     * Modify cron expression
    void modify();

// Expression-related interface implementation
public class SwitchServiceImpl implements SwitchService {

    private static String DB_CRON = "";

    public String getCron(String taskId) {
        System.out.println("Execute database queries DB_CRON " + LocalDateTime.now());
        return DB_CRON;

    public void modify() {
        DB_CRON = "0/20 * * * * *";
        System.out.println("Modify the database DB_CRON " + LocalDateTime.now());

Simulate modifications and queries here

2) Create specific task execution

public class DynamicCronTask implements SchedulingConfigurer {
    // Simulate current task ID
    private String TASK_ID = "5001";

    private SwitchService switchService;

    private String SpringDynamicCronTask() {
        // Default execution every 5 seconds
        String cron = "0/5 * * * * ?";
        //Get the configuration corn s expression from the database
        String dbCron = switchService.getCron(TASK_ID);
        // Use the default expression when the query is empty
        if (StringUtils.isNotBlank(dbCron)) {
            return dbCron;
        return cron;

    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.addTriggerTask(new Runnable() {
            public void run() {
                // Task logic
                System.out.println("Execute Task Logic...." + LocalDateTime.now());
        }, new Trigger() {
            public Date nextExecutionTime(TriggerContext triggerContext) {
                String s = SpringDynamicCronTask();
                // Task triggers that modify the execution cycle of a task
                CronTrigger trigger = new CronTrigger(s);
                Date nextExec = trigger.nextExecutionTime(triggerContext);
                return nextExec;


3) Start Services

View Execution Log

Execute database query DB_CRON 2020-06-09T10:33:30.001
 Execute Task Logic....2020-06-09T10:33:35.002
 Execute database query DB_CRON 2020-06-09T10:33:35.002
 Execute Task Logic....2020-06-09T10:33:40.001
 Execute database query DB_CRON 2020-06-09T10:33:40.001

Modify DB_in the databaseCRON 2020-06-09T10:33:42.085

Execute Task Logic....2020-06-09T10:33:45
 Execute database query DB_CRON 2020-06-09T10:33:45

Execute Task Logic....2020-06-09T10:34:00.001
 Execute database query DB_CRON 2020-06-09T10:34:00.001
 Execute Task Logic....2020-06-09T10:34:20.002
 Execute database query DB_CRON 2020-06-09T10:34:20.002

From the log, you can see that when the application starts, the execution cycle of the configuration is queried from the database first, then the timed task is executed, then the execution cycle is queried again after execution, and the next execution time is executed according to the modified execution time.

Effective time will not take effect immediately after the next execution time is over!!!

Keywords: Web Development Database Spring Hibernate MySQL

Added by Desbrina on Mon, 15 Jun 2020 21:10:56 +0300