好的,阿杰,我来帮你整理一份 Spring 定时任务 TaskScheduler 详解,内容会涵盖原理、常用配置、用法和实战示例。


Spring 定时任务 TaskScheduler 详解

在 Spring 中,定时任务主要依赖 TaskScheduler 接口 来实现。
相比传统的 TimerScheduledExecutorService,Spring 提供了更强大、更灵活的任务调度支持。


1. TaskScheduler 简介

  • 接口org.springframework.scheduling.TaskScheduler
  • 作用:用于调度和管理定时任务。
  • 常见实现类
    • ThreadPoolTaskScheduler(最常用,基于线程池)
    • ConcurrentTaskScheduler(简单包装 JDK 的 ScheduledExecutorService

TaskScheduler 可以调度:

  • 一次性任务(在某个时间点执行)
  • 固定速率任务(每隔固定时间间隔执行)
  • 固定延迟任务(前一次执行结束后延迟一段时间再执行)
  • 基于 Cron 表达式的任务

2. 常用方法

TaskScheduler 接口常用方法:

ScheduledFuture<?> schedule(Runnable task, Trigger trigger);
ScheduledFuture<?> schedule(Runnable task, Date startTime);
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period);
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period);
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay);

方法说明

  1. schedule
    • schedule(Runnable task, Date startTime):在指定时间执行一次任务。
    • schedule(Runnable task, Trigger trigger):根据触发器(如 CronTrigger)执行任务。
  2. scheduleAtFixedRate
    • 固定速率执行,即每隔一段时间执行一次,不考虑上一次任务执行耗时。
  3. scheduleWithFixedDelay
    • 固定延迟执行,即等待上一次任务完成后,延迟一段时间再执行下一次。

3. 配置 TaskScheduler

3.1 基本配置

Spring 推荐使用 ThreadPoolTaskScheduler

@Configuration
@EnableScheduling
public class SchedulerConfig {

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5); // 设置线程池大小
        scheduler.setThreadNamePrefix("task-"); // 线程名前缀
        scheduler.setRemoveOnCancelPolicy(true); // 任务取消后移除
        scheduler.initialize();
        return scheduler;
    }
}


4. 使用示例

4.1 固定速率任务

@Component
public class FixedRateTask {

    @Autowired
    private TaskScheduler taskScheduler;

    @PostConstruct
    public void scheduleFixedRateTask() {
        taskScheduler.scheduleAtFixedRate(() -> {
            System.out.println("固定速率任务执行时间:" + new Date());
        }, 5000); // 每 5 秒执行一次
    }
}


4.2 固定延迟任务

@Component
public class FixedDelayTask {

    @Autowired
    private TaskScheduler taskScheduler;

    @PostConstruct
    public void scheduleFixedDelayTask() {
        taskScheduler.scheduleWithFixedDelay(() -> {
            System.out.println("固定延迟任务执行时间:" + new Date());
            try {
                Thread.sleep(2000); // 模拟任务耗时
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 3000); // 上次任务完成后,延迟 3 秒再执行
    }
}


4.3 Cron 表达式任务

@Component
public class CronTask {

    @Autowired
    private TaskScheduler taskScheduler;

    @PostConstruct
    public void scheduleCronTask() {
        taskScheduler.schedule(() -> {
            System.out.println("Cron 任务执行时间:" + new Date());
        }, new CronTrigger("0/10 * * * * ?")); // 每 10 秒执行一次
    }
}


5. TaskScheduler 与 @Scheduled 的关系

  • @Scheduled 是 Spring 提供的更简单的注解方式,本质上依赖 TaskScheduler
  • 如果需要更精细化的控制(动态创建、取消任务),就需要手动注入 TaskScheduler 来管理。

示例(注解方式):

@Component
public class AnnotationTask {

    @Scheduled(cron = "0/15 * * * * ?")
    public void doTask() {
        System.out.println("注解方式执行:" + new Date());
    }
}


6. 动态任务管理

可以手动保存 ScheduledFuture<?>,在运行时动态 启动/取消 任务:

@Component
public class DynamicTaskManager {

    @Autowired
    private TaskScheduler taskScheduler;

    private ScheduledFuture&lt;?> future;

    public void startTask() {
        future = taskScheduler.scheduleAtFixedRate(() -> {
            System.out.println("动态任务执行:" + new Date());
        }, 5000);
    }

    public void stopTask() {
        if (future != null) {
            future.cancel(true);
        }
    }
}


7. 小结

  • TaskScheduler 是 Spring 定时任务的核心接口。
  • 常见实现类:ThreadPoolTaskScheduler(推荐)。
  • 支持四种方式:一次性、固定速率、固定延迟、Cron 表达式。
  • 适合需要 动态任务管理 的场景,比 @Scheduled 更灵活。