Spring Task
Spring Task 是 Spring 内置的轻量级定时任务模块,提供任务调度和异步执行功能。
定时调度
XML 配置
<task:scheduler id="scheduler" pool-size="3" />
<bean id="task" class="task.Task"/>
<task:scheduled-tasks scheduler="scheduler">
<task:scheduled ref="task" method="print" cron="0/5 * * * * ?"/>
</task:scheduled-tasks>注解配置
@EnableScheduling
@Configuration
public class ScheduleConfig {
@Scheduled(cron = "0 0 9 * * ?")
public void dailyTask() {
// 每天 9 点执行
}
@Scheduled(fixedRate = 5000)
public void fixedRateTask() {
// 每 5 秒执行一次
}
@Scheduled(fixedDelay = 5000)
public void fixedDelayTask() {
// 上次完成后间隔 5 秒
}
}任务类型
| 类型 | 说明 |
|---|---|
| CronTask | Cron 表达式定时执行 |
| TriggerTask | Trigger 接口自定义触发 |
| IntervalTask.fixedDelay | 固定延迟(上一次完成后间隔 N 毫秒) |
| IntervalTask.fixedRate | 固定频率(每 N 毫秒执行一次) |
解析机制
SchedulerBeanDefinitionParser 将 task:scheduler 解析为 ThreadPoolTaskScheduler。
调度入口:ContextLifecycleScheduledTaskRegistrar.afterSingletonsInstantiated → scheduleTasks()
CronTask 构造器将字符串表达式转为 CronTrigger,内部使用 CronSequenceGenerator 解析。
Trigger 接口
public interface Trigger {
Date nextExecutionTime(TriggerContext triggerContext);
}实现类:CronTrigger(基于 Cron)、PeriodicTrigger(基于固定间隔)。
异步执行
<task:executor id="executor" pool-size="3"/>
<task:annotation-driven executor="executor"/>@EnableAsync
@Configuration
public class AsyncConfig { }
@Async("executor")
public void print() {
System.out.println("异步执行");
}提示
实现原理 Spring 为带有 @Async 的组件生成代理子类,方法被包装为 Runnable 提交到线程池执行。同类方法内调用会绕过代理,导致异步失效。
与 Quartz 对比
| 特性 | Spring Task | Quartz |
|---|---|---|
| 复杂度 | 轻量 | 重量 |
| Cron 支持 | 支持 | 支持 |
| 集群支持 | 不支持 | 支持 |
| 持久化 | 不支持 | 支持 |
| 线程池 | ThreadPoolTaskScheduler | 自带线程池 |
注意
选型建议 简单定时任务选 Spring Task;需要集群调度、任务持久化等复杂场景选 Quartz。
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 定时任务不执行 | 未启用 @EnableScheduling | 在启动类或配置类添加注解 |
| Cron 表达式格式错误 | Spring 使用 6 位(含秒),不是 Linux 的 5 位 | 使用 秒 分 时 日 月 周 格式 |
| @Async 方法同步执行 | 未启用 @EnableAsync 或同类调用 | 添加 @EnableAsync;将异步方法移到另一个 Bean |
| 线程池耗尽 | 默认单线程,任务阻塞时后续排队 | 配置 task:executor 增大 pool-size |