SpringBoot定时器

在Spring Boot中实现定时任务主要依赖 @Scheduled 注解和 @EnableScheduling 注解。以下是完整使用指南和时间规则详解:


一、快速启用定时任务

1. 主启动类开启支持
@SpringBootApplication
@EnableScheduling // 核心注解:启用定时任务
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
2. 创建定时任务类
@Component // 必须声明为Spring组件
public class ScheduledTasks {
    
    // 每5秒执行一次
    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        System.out.println("定时任务执行: " + new Date());
    }
}

二、六种时间规则配置方式

1. Cron表达式(最灵活)

格式秒 分 时 日 月 周 [年]
字段范围

字段允许值特殊符号
0-59, - * /
0-59, - * /
0-23, - * /
1-31, - * ? / L W C
1-12 或 JAN-DEC, - * /
1-7 或 SUN-SAT, - * ? / L C #
可选 1970-2099, - * /

常用示例

@Scheduled(cron = "0 0 3 * * ?")     // 每天凌晨3点执行
@Scheduled(cron = "0 0/30 9-17 * * MON-FRI")  // 工作日9:00-17:30每半小时
@Scheduled(cron = "0 15 10 L * ?")   // 每月最后一天10:15执行
@Scheduled(cron = "0 0 12 ? * WED")  // 每周三中午12点

符号说明

  • * : 所有值
  • ? : 不指定(日/周冲突时使用)
  • - : 范围(如9-17)
  • / : 间隔(0/15每15秒)
  • L : 最后(日:月末;周:周六)
  • W : 最近工作日(15W:距离15日最近的工作日)
  • # : 第几个周几(6#3:每月第3个周五)

2. 固定速率(fixedRate)
@Scheduled(fixedRate = 5000) // 每5秒执行一次(从上次开始时间算)
public void fixedRateTask() {
    // 任务代码
}

特性

  • 始终按固定频率执行,不等待上次任务完成
  • 适用于独立任务(无状态)

3. 固定延迟(fixedDelay)
@Scheduled(fixedDelay = 3000) // 上次执行结束后3秒执行
public void fixedDelayTask() {
    // 模拟耗时任务
    Thread.sleep(1000); 
}

特性

  • 严格保证任务间隔(含执行时间)
  • 适用于有先后依赖的任务

4. 初始延迟(initialDelay + fixed)
@Scheduled(
  initialDelay = 10000, // 应用启动10秒后首次执行
  fixedRate = 60000      // 之后每1分钟执行
)
public void delayedStartTask() {
    // 初始化类任务
}

5. 时间单位配置

支持时间单位参数:

@Scheduled(fixedRateString = "5000", timeUnit = TimeUnit.MILLISECONDS)
@Scheduled(fixedDelay = 2, timeUnit = TimeUnit.HOURS) // 每2小时

6. 属性文件配置(动态修改)
# application.properties
task.interval=0 0/5 * * * ?
@Scheduled(cron = "${task.interval}")
public void dynamicScheduleTask() {
    // 动态读取配置
}

三、高级配置技巧

1. 线程池调优(避免单线程阻塞)
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(
            Executors.newScheduledThreadPool(10) // 自定义10线程池
        );
    }
}
2. 异常处理
@Scheduled(fixedRate = 5000)
public void taskWithException() {
    try {
        // 业务代码
    } catch (Exception e) {
        logger.error("定时任务异常", e); // 必须捕获异常
    }
}
3. 分布式锁(集群环境)
@Scheduled(cron = "0 */1 * * * ?")
public void distributedTask() {
    if(redisLock.tryLock("taskLock", 30)) { // Redis锁
        try {
            // 执行任务
        } finally {
            redisLock.unlock("taskLock");
        }
    }
}

四、避坑指南

问题场景解决方案
任务阻塞增加线程池大小;异步执行
集群重复执行添加分布式锁机制
配置不生效检查是否添加 @EnableScheduling
Cron表达式错误使用 Cron在线验证工具
容器关闭任务继续实现 DisposableBean 销毁任务
毫秒级精度不足使用 ScheduledExecutorService

五、监控方案(Spring Boot Actuator)

# application.yml
management:
  endpoint:
    scheduledtasks:
      enabled: true
  endpoints:
    web:
      exposure:
        include: scheduledtasks

访问端点查看任务列表:
http://localhost:8080/actuator/scheduledtasks


六、完整示例

@Component
public class AdvancedScheduler {

    // 工作日9点到18点,每15分钟执行
    @Scheduled(cron = "0 0/15 9-18 * * MON-FRI")
    public void businessHoursTask() {
        // 业务处理
    }

    // 带初始延迟的每日备份
    @Scheduled(
        initialDelay = 30000, 
        fixedDelay = 24 * 60 * 60 * 1000
    )
    public void dailyBackup() throws Exception {
        // 数据备份操作
    }
    
    // 使用属性配置动态间隔
    @Scheduled(cron = "${backup.cron}")
    public void dynamicBackup() {
        // 动态任务
    }
}

通过合理组合这些方法,即可实现各类复杂定时任务需求。建议优先使用Cron表达式实现灵活性,同时注意线程管理和异常处理确保稳定性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

堕落年代

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值