SpringBoot 实现动态的定时任务

背景

在实际开发中,定时任务的执行周期可能需要动态调整。SpringBoot 的 @Scheduled 注解不支持运行时修改 cron 表达式,但通过 SchedulingConfigurerScheduledTaskRegistrar 可以实现动态调度。

核心步骤
  1. 依赖配置
    确保项目中引入 spring-boot-starter,默认包含定时任务支持。

  2. 动态任务类
    继承 SchedulingConfigurer,通过 ScheduledTaskRegistrar 注册任务。关键方法:

    • configureTasks():初始化任务。
    • updateCron():修改 cron 表达式并重启任务。
    • restartTask():取消旧任务并启动新任务。
  3. REST API 支持
    提供 HTTP 接口,调用 updateCron 方法动态调整 cron 表达式。例如:

    curl -X POST http://localhost:8080/schedule/update?cron=0/10 * * * * ?
    
  4. 测试验证
    启动应用后,观察日志输出频率是否随 cron 表达式变化而改变。

注意事项
  • 线程安全ScheduledFuture 的取消和重启需同步处理(示例未展示,实际需加锁)。
  • 表达式校验:调用 updateCron 前需验证 cron 表达式合法性。
  • 任务持久化:若需持久化 cron 表达式,可结合数据库存储。
完整代码

参考上述代码案例,直接复制到 SpringBoot 项目中即可运行。


通过这种方式,可以灵活应对定时任务调度需求的变化。

SpringBoot 实现动态的修改定时任务

SpringBoot 中动态修改定时任务的 cron 表达式可以通过 ScheduledTaskRegistrar 和自定义任务调度实现。以下是一个完整的代码案例,包含核心逻辑和博文内容。


代码案例

1. 添加依赖

确保 pom.xml 中包含 SpringBoot 定时任务依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
2. 动态任务配置类

创建一个动态任务注册器,支持运行时修改 cron 表达式:

import org.springframework.scheduling.TaskScheduler;
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.util.concurrent.ScheduledFuture;

@Component
public class DynamicScheduledTask implements SchedulingConfigurer {

    private final TaskScheduler taskScheduler;
    private ScheduledFuture<?> scheduledFuture;
    // 默认每5秒执行一次 
    private String currentCron = "0/5 * * * * ?"; 

    public DynamicScheduledTask(TaskScheduler taskScheduler) {
        this.taskScheduler = taskScheduler;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        restartTask();
    }

    // 动态修改 cron 表达式并重启任务
    public void updateCron(String newCron) {
        this.currentCron = newCron;
        restartTask();
    }

    private void restartTask() {
        if (scheduledFuture != null) {
            scheduledFuture.cancel(true); // 取消旧任务
        }
        scheduledFuture = taskScheduler.schedule(
            this::executeTask,
            new CronTrigger(currentCron)
        );
    }

    private void executeTask() {
        System.out.println("Dynamic task executed at: " + System.currentTimeMillis());
    }
}
3. 控制器接口

提供一个 REST API 来动态修改 cron 表达式:

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/schedule")
public class ScheduleController {

    private final DynamicScheduledTask dynamicScheduledTask;

    public ScheduleController(DynamicScheduledTask dynamicScheduledTask) {
        this.dynamicScheduledTask = dynamicScheduledTask;
    }

    @PostMapping("/update")
    public String updateCron(@RequestParam String cron) {
        dynamicScheduledTask.updateCron(cron);
        return "Cron updated to: " + cron;
    }
}
4. 启动类

确保启动类启用定时任务:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐