在Spring里,可以用
@Scheduled
注解来创建定时任务先说缺点, Spring Task不支持集群部署,无法持久化,无法动态修改执行时间,没有监控报警,所以只适合简单的单体应用部署
如何使用
启用
在项目启动类或者配置类加上
@EnableScheduling
就可以启用定时任务配置, 可以跳过此步,使用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); } }
使用
在方法上使用
@Scheduled
来开启定时任务@Scheduled
支持4种定时策略cron 表达式: 最灵活,支持按秒、分、时、日、月、周等复杂调度
固定频率执行: 每隔固定时间执行一次,不管上一次是否完成
固定延迟执行: 上一次执行结束后,再延迟固定时间执行
初始延迟 + 固定频率/延迟: 第一次执行前先延迟一段时间
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. 调度器在指定时间调用目标方法(通过反射)