Spring Boot 定时任务完全指南:@Scheduled 与 cron
Spring Boot 提供了简单易用的定时任务支持。本文介绍 @Scheduled 注解的使用方法。
启用定时任务
@SpringBootApplication
@EnableScheduling // 启用定时任务
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Scheduled 注解
基本用法
@Component
public class MyTask {
@Scheduled(fixedRate = 5000) // 每5秒执行一次
public void execute() {
System.out.println("执行任务: " + LocalDateTime.now());
}
}
参数说明
| 参数 | 说明 | 示例 |
|---|---|---|
| fixedRate | 固定频率(毫秒) | fixedRate = 5000 |
| fixedDelay | 固定延迟(毫秒) | fixedDelay = 5000 |
| cron | Cron 表达式 | cron = “0 0 9 * * ?” |
| initialDelay | 初始延迟(毫秒) | initialDelay = 10000 |
Cron 表达式
@Component
public class ScheduledTasks {
// 每天 9:00 执行
@Scheduled(cron = "0 0 9 * * ?")
public void dailyTask() {
System.out.println("每日任务");
}
// 每小时执行
@Scheduled(cron = "0 0 */1 * * ?")
public void hourlyTask() {
System.out.println("每小时任务");
}
// 工作日 9:00 执行
@Scheduled(cron = "0 0 9 ? * MON-FRI")
public void weekdayTask() {
System.out.println("工作日任务");
}
}
fixedRate vs fixedDelay
fixedRate
@Scheduled(fixedRate = 5000)
public void task() {
// 每5秒开始执行一次
// 如果任务执行时间超过5秒,会立即执行下一次
}
fixedDelay
@Scheduled(fixedDelay = 5000)
public void task() {
// 上一次执行完成后,等待5秒再执行
// 保证任务之间有固定间隔
}
异步定时任务
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
public Executor taskExecutor() {
return Executors.newFixedThreadPool(10);
}
}
@Component
public class AsyncTask {
@Async
@Scheduled(fixedRate = 5000)
public void asyncTask() {
// 异步执行,不阻塞调度线程
}
}
动态定时任务
@Component
public class DynamicTask implements SchedulingConfigurer {
private String cron = "0 0 9 * * ?";
@Override
public void configureTasks(ScheduledTaskRegistrar registrar) {
registrar.addTriggerTask(
() -> System.out.println("动态任务"),
triggerContext -> {
CronTrigger trigger = new CronTrigger(cron);
return trigger.nextExecution(triggerContext);
}
);
}
public void setCron(String cron) {
this.cron = cron;
}
}
定时任务线程池
# application.yml
spring:
task:
scheduling:
pool:
size: 10
thread-name-prefix: scheduled-
最佳实践
- 异常处理:定时任务中的异常不会抛出,需要自行处理
- 日志记录:记录任务开始和结束时间
- 幂等性:任务应该支持重复执行
- 超时控制:设置任务超时时间
- 监控告警:任务失败时发送告警
@Component
public class SafeTask {
private static final Logger log = LoggerFactory.getLogger(SafeTask.class);
@Scheduled(cron = "0 0 9 * * ?")
public void execute() {
try {
log.info("任务开始");
long start = System.currentTimeMillis();
// 执行业务逻辑
doBusiness();
log.info("任务完成,耗时: {}ms", System.currentTimeMillis() - start);
} catch (Exception e) {
log.error("任务执行失败", e);
// 发送告警
}
}
}
总结
Spring Boot 的 @Scheduled 注解提供了简单易用的定时任务支持。对于简单场景,使用 @Scheduled;对于复杂场景,可以集成 Quartz。