在Spring里,可以用@Scheduled注解来创建定时任务

先说缺点, Spring Task不支持集群部署,无法持久化,无法动态修改执行时间,没有监控报警,所以只适合简单的单体应用部署

如何使用

  1. 启用

    在项目启动类或者配置类加上@EnableScheduling就可以启用定时任务

     

  2. 配置, 可以跳过此步,使用Spring默认配置

    @Configuration
    @EnableScheduling
    public class SchedulingConfig implements SchedulingConfigurer {
    
        @Override
        public void configureTasks(ScheduledTaskRegistrar registrar) {
            ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    
            // 定时任务线程名称前缀
            scheduler.setThreadNamePrefix("scheduled-task-");
            // 设置线程数,默认线程数的是1,所有定时任务会串行执行,所以这里设置一下线程数
            scheduler.setPoolSize(5);
            // 初始化
            scheduler.initialize();
    
            registrar.setTaskScheduler(scheduler);
        }
    }
    

     

  3. 使用

    在方法上使用@Scheduled来开启定时任务

    @Scheduled支持4种定时策略

    1. cron 表达式: 最灵活,支持按秒、分、时、日、月、周等复杂调度

    2. 固定频率执行: 每隔固定时间执行一次,不管上一次是否完成

    3. 固定延迟执行: 上一次执行结束后,再延迟固定时间执行

    4. 初始延迟 + 固定频率/延迟: 第一次执行前先延迟一段时间

    4种定时策略示例:

    @Component
    public class DemoScheduler {
    
        // cron: cron 表达式
        @Scheduled(cron = "0 0 2 * * ?")
        public void dailyBackup() {
            // 每天凌晨2点执行
        }
    
        // fixedRate: 固定频率执行
        @Scheduled(fixedRate = 5000)
        public void reportStatus() {
            // 每 5 秒执行一次,不管上一次是否完成
        }
    
        // fixedDelay:固定延迟执行
        @Scheduled(fixedDelay = 5000)
        public void fetchData() {
            // 上一次执行结束后,再等 5 秒执行下一次
        }
    
        // initialDelay + fixedRate 或 fixedDelay:初始延迟
        @Scheduled(fixedRate = 5000, initialDelay = 10000)
        public void initCache() {
            // 启动后延迟 10 秒执行第一次,之后每 5 秒执行一次
        }
    
        @Scheduled(fixedDelay = 3000, initialDelay = 5000)
        public void checkHealth() {
            // 启动后延迟 5 秒执行第一次,之后每次执行完再等 3 秒
        }
    }
    

原理

@Scheduled 的实现基于 Spring 的后置处理器(BeanPostProcessor)机制任务调度器(TaskScheduler),整体流程如下:

1. @EnableScheduling 触发配置导入
2. Spring 扫描所有 Bean 中的 @Scheduled 方法
3. 解析 cron/fixedDelay/fixedRate 等元数据
4. 将任务注册到 TaskScheduler(调度器)
5. 调度器在指定时间调用目标方法(通过反射)