Spring Task 介绍与基本使用
1. 什么是 Spring Task?
Spring Task 是 Spring 框架提供的 轻量级任务调度模块,用于在应用程序中实现定时任务、周期性任务或延迟任务。它通过注解和配置简化了任务调度的开发,适用于单机环境下的简单调度需求。
2. 核心组件
-
@Scheduled
注解:标记需要定时执行的方法。 -
TaskScheduler
:任务调度器,负责根据规则触发任务。 -
Cron 表达式
:定义复杂的时间调度规则(如每天凌晨执行)。 -
TaskExecutor
:任务执行器,控制任务执行的线程池。
3. 快速入门(Spring Boot 示例)
3.1 启用任务调度
在 Spring Boot 启动类添加 @EnableScheduling
注解:
@SpringBootApplication @EnableScheduling // 启用任务调度 public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);} }
3.2 定义定时任务
在 Bean 中使用 @Scheduled
注解标记方法:
@Component public class MyTask {// 每隔 5 秒执行一次@Scheduled(fixedRate = 5000)public void task1() {System.out.println("Fixed Rate Task: " + new Date());}// 每天 12:00 执行@Scheduled(cron = "0 0 12 * * ?")public void task2() {System.out.println("Cron Task: Lunch Time!");} }
4. @Scheduled
参数详解
-
fixedRate
:固定速率,上次任务开始后间隔指定时间执行。@Scheduled(fixedRate = 5000) // 单位:毫秒
-
fixedDelay
:固定延迟,上次任务结束后间隔指定时间执行。@Scheduled(fixedDelay = 3000)
-
initialDelay
:首次任务延迟时间。@Scheduled(initialDelay = 1000, fixedRate = 5000)
-
cron
:使用 Cron 表达式定义复杂规则。@Scheduled(cron = "0 0/30 9-17 * * MON-FRI") // 工作日每半小时执行
5. Cron 表达式语法
Cron 表达式由 6~7 个字段 组成,格式为:秒 分 时 日 月 周 [年]
(年可选)
字段 | 允许值 | 特殊字符 |
---|---|---|
秒 | 0-59 | , - * / |
分 | 0-59 | , - * / |
时 | 0-23 | , - * / |
日 | 1-31 | , - * ? / L W |
月 | 1-12 或 JAN-DEC | , - * / |
周 | 1-7 或 SUN-SAT | , - * ? / L # |
年 | 1970-2099 | , - * / |
示例:
-
0 0 12 * * ?
:每天 12:00 执行。 -
0 0/5 14,18 * * ?
:每天 14 点和 18 点,每隔 5 分钟执行。 -
0 15 10 ? * MON-FRI
:工作日 10:15 执行。
6. 配置线程池
默认情况下,所有任务在 单线程 中执行。若需并发执行,需自定义线程池:
@Configuration public class TaskConfig implements SchedulingConfigurer {@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));} }
7. 常见问题与解决
-
问题1:任务阻塞导致后续任务延迟
解决:使用@Async
异步执行,或增大线程池大小。@Async @Scheduled(fixedRate = 1000) public void asyncTask() {// 异步任务逻辑 }
-
问题2:任务需手动启停
解决:通过ScheduledFuture
控制任务。@Autowired private TaskScheduler taskScheduler;private ScheduledFuture<?> future;public void startTask() {future = taskScheduler.schedule(() -> System.out.println("Dynamic Task"), new CronTrigger("0/5 * * * * ?")); }public void stopTask() {if (future != null) future.cancel(true); }
8. Spring Task vs Quartz
特性 | Spring Task | Quartz |
---|---|---|
复杂度 | 轻量级,配置简单 | 功能丰富,配置复杂 |
分布式支持 | 不支持(单机) | 支持(需数据库) |
任务持久化 | 不支持 | 支持 |
适用场景 | 简单定时任务、单机环境 | 复杂调度、分布式集群环境 |
9. 最佳实践
-
避免长时间阻塞任务:确保任务快速执行,或使用异步线程。
-
合理配置线程池:根据任务数量调整线程池大小。
-
使用 Cron 表达式:灵活控制复杂调度逻辑。
-
日志与监控:记录任务执行状态,便于排查问题。