前言
在 spring boot 中,@scheduled 注解是实现定时任务最常用且便捷的方式,它基于 spring 的 task scheduling 框架,支持多种触发规则,如固定间隔、固定延迟和 cron 表达式。
基本使用步骤
启用定时任务:在 spring boot 的主启动类或任意
@configuration配置类上添加@enablescheduling注解,以开启对@scheduled注解的支持。@springbootapplication @enablescheduling public class myapplication { public static void main(string[] args) { springapplication.run(myapplication.class, args); } }创建定时任务:在任意 spring 管理的 bean(如
@component、@service等)中,将需要定时执行的方法上添加@scheduled注解,并指定触发规则。
@scheduled 的触发方式
@scheduled 注解提供了多种方式来定义任务执行的时间规则,必须且只能选择其中一种。
cron表达式(最灵活):使用 cron 表达式可以精确控制任务在特定的时间点执行,例如每天、每周的特定时刻。@component public class crontask { // 每天凌晨 2 点执行 @scheduled(cron = "0 0 2 * * ?") public void dailytask() { system.out.println("每日定时任务执行: " + new date()); } // 每 5 秒执行一次 @scheduled(cron = "0/5 * * * * ?") public void everyfiveseconds() { system.out.println("每5秒执行: " + new date()); } }
fixedrate(固定速率):从上一次任务开始执行的时间点算起,每隔指定的毫秒数执行一次。无论上一次任务是否执行完毕,到时间点就会触发下一次执行。@component public class fixedratetask { // 每 5000 毫秒(5秒)执行一次,从方法开始执行时计时 @scheduled(fixedrate = 5000) public void fixedratetask() { system.out.println("固定速率任务执行: " + new date()); try { thread.sleep(3000); // 模拟任务执行耗时3秒 } catch (interruptedexception e) { e.printstacktrace(); } } }
fixeddelay(固定延迟):从上一次任务执行结束的时间点算起,等待指定的毫秒数后,再执行下一次任务。这种方式能确保任务不会重叠。@component public class fixeddelaytask { // 上一次任务执行结束后,等待 5000 毫秒(5秒)再执行下一次 @scheduled(fixeddelay = 5000) public void fixeddelaytask() { system.out.println("固定延迟任务执行: " + new date()); try { thread.sleep(3000); // 模拟任务执行耗时3秒 } catch (interruptedexception e) { e.printstacktrace(); } } }
initialdelay(初始延迟):通常与fixedrate或fixeddelay配合使用,用于指定任务在应用启动后,首次执行前的延迟时间。
@component
public class initialdelaytask {
// 应用启动后延迟 10 秒,之后每隔 5 秒执行一次
@scheduled(initialdelay = 10000, fixedrate = 5000)
public void initialdelaytask() {
system.out.println("初始延迟任务执行: " + new date());
}
}
cron 表达式语法
cron 表达式由 6 或 7 个字段组成(秒 分 时 日 月 周 [年]),字段间用空格分隔。常用符号如下:
| 字段 | 允许值 | 特殊符号 | 说明 |
|---|---|---|---|
| 秒 | 0-59 | * / , - | * 表示每秒,/ 表示间隔(如 5/15 表示 5, 20, 35, 50 秒),, 表示列举(如 5,20) |
| 分 | 0-59 | * / , - | |
| 时 | 0-23 | * / , - | |
| 日 | 1-31 | * / , - ? l w | ? 表示不指定,l 表示最后一天,w 表示最近的工作日 |
| 月 | 1-12 或 jan-dec | * / , - | |
| 周 | 1-7 或 sun-sat | * / , - ? l # | ? 表示不指定,l 表示最后一天,# 表示第几个(如 6#3 表示每月第三个星期五) |
| 年 | 1970-2099 | * / , - | 可选 |
常见示例:
0 0 12 * * ?:每天中午 12:00:00 执行。0 15 10 ? * *:每天上午 10:15:00 执行。0 0/5 * * * ?:每 5 分钟执行一次。0 0 2 ? * 6l:每月最后一个星期五的凌晨 2:00:00 执行。0 0 12 15 * ?:每月 15 日中午 12:00:00 执行。
多线程与并发执行
默认情况下,spring boot 的 @scheduled 任务是单线程串行执行的。这意味着如果一个任务执行时间过长,会阻塞其他任务的执行。
要实现多任务并发执行,需要自定义一个 taskscheduler bean,并设置线程池大小:
@configuration
public class schedulerconfig {
@bean
public taskscheduler taskscheduler() {
threadpooltaskscheduler scheduler = new threadpooltaskscheduler();
scheduler.setpoolsize(10); // 设置线程池大小为10
scheduler.setthreadnameprefix("scheduled-task-");
scheduler.setwaitfortaskstocompleteonshutdown(true);
scheduler.initialize();
return scheduler;
}
}
此外,如果任务本身是耗时操作(如调用外部 api),可以结合 @async 注解实现异步执行,但这需要额外配置 @enableasync。
注意事项
- 时区问题:cron 表达式默认使用服务器的本地时区。如需指定时区,可使用
zone属性,例如@scheduled(cron = "0 0 2 * * ?", zone = "asia/shanghai")。 - 分布式环境:在多个服务实例部署时,每个实例都会执行定时任务,可能导致任务重复执行。此时应考虑使用分布式调度框架(如 xxl-job、quartz)或结合 redis 分布式锁来保证任务的唯一性。
- 任务持久化:
@scheduled任务是内存级的,应用重启后任务信息会丢失。如需持久化,需集成 quartz 等框架。
总结
到此这篇关于spring boot中使用@scheduled做定时任务的基本步骤的文章就介绍到这了,更多相关springboot @scheduled做定时任务内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论