Spring Task定时任务全解析:从入门到实战

Hello,大家好,我是Yize,在进行学习时遇到了SpringTask ,因为感觉挺有趣,而且很实用,索性就去了解了一点,下面就跟我一起来学习吧!!

目录

[一、什么是 Spring Task?](#一、什么是 Spring Task?)

二、核心注解

三、三种配置方式

[1. 固定延迟(fixedDelay)](#1. 固定延迟(fixedDelay))

[2. 固定速率(fixedRate)](#2. 固定速率(fixedRate))

[3. Cron 表达式(最常用 ⭐)](#3. Cron 表达式(最常用 ⭐))

[四、Cron 表达式详解(重点!)](#四、Cron 表达式详解(重点!))

常用通配符

[🔥 常见 Cron 示例速查表](#🔥 常见 Cron 示例速查表)

五、完整代码示例

第一步:启动类加注解

第二步:编写定时任务类

[六、苍穹外卖中的实际应用场景 🍔](#六、苍穹外卖中的实际应用场景 🍔)

场景1:定时清理过期订单

场景2:定时处理「已完成」的订单

场景3:定时推送营业提醒

[七、注意事项 ⚠️](#七、注意事项 ⚠️)

[🚀 多线程优化(进阶)](#🚀 多线程优化(进阶))

八、总结脑图


一、什么是 Spring Task?

Spring Task ​ 是 Spring 框架提供的定时任务解决方案,允许你在指定的时间自动执行某些代码逻辑,无需额外引入第三方框架(如 Quartz)。

核心思想:通过注解配置,让某个方法在指定时间自动执行。


二、核心注解

注解 作用 说明
@EnableScheduling 开启定时任务支持 加在启动类配置类
@Scheduled 标记定时执行的方法 加在方法

三、三种配置方式

1. 固定延迟(fixedDelay

上一次执行完成后,间隔指定时间再执行。

复制代码
@Scheduled(fixedDelay = 5000)  // 上次任务结束后,等5秒再执行
public void task1() {
    System.out.println("fixedDelay 执行:" + LocalDateTime.now());
}

⏱️ 场景:适合任务执行时间不确定,需要"做完一个再等一会儿做下一个"的情况。


2. 固定速率(fixedRate

每隔指定时间执行一次,不管上次是否执行完。

复制代码
@Scheduled(fixedRate = 3000)  // 每3秒执行一次
public void task2() {
    System.out.println("fixedRate 执行:" + LocalDateTime.now());
}

⏱️ 场景:适合任务执行时间稳定、需要严格按频率执行的场景。


3. Cron 表达式(最常用 ⭐)

通过 Cron 表达式灵活控制执行时间。

复制代码
@Scheduled(cron = "0 0 12 * * ?")  // 每天中午12点执行
public void task3() {
    System.out.println("Cron 执行:" + LocalDateTime.now());
}

四、Cron 表达式详解(重点!)

Cron 表达式由 6~7 个字段​ 组成:

复制代码
秒  分  时  日  月  周  年(可选)
*   *   *   *   *   *   ?
字段 含义 取值范围
Seconds 0-59
Minutes 0-59
Hours 0-23
Day of Month 1-31
Month 1-12
Day of Week 1-7(1=周日)或 MON-SUN
Year(可选) 留空即可

常用通配符

符号 含义 示例
* 所有值 * 表示每秒/每分/每小时
? 不指定(日和周互斥时用) ? 用在日或周字段
- 范围 10-12 → 10、11、12
, 枚举多个值 1,3,5 → 1、3、5
/ 步长(每隔) 0/5 → 每5个单位
L 最后 L 表示最后一天
W 最近工作日 15W → 15号最近的工作日

🔥 常见 Cron 示例速查表

表达式 含义
0 0 0 * * ? 每天凌晨0点
0 30 8 * * ? 每天早上8:30
0 0 12 * * ? 每天中午12:00
0 0 0 ? * MON 每周一凌晨0点
0 0 0 1 * ? 每月1号凌晨0点
0 0 0 1 1 ? 每年1月1日0点
0 */5 * * * ? 每5分钟执行一次
0 0 8-18 * * ? 每天8点到18点整点执行
0 0 0 L * ? 每月最后一天0点
0 0 0 ? * 6L 每月最后一个周五0点

💡 记忆口诀 :日和周只能指定一个,另一个用 ? 占位。

💡 Cron 表达式在线生成器: https://cron.ciding.cc/


五、完整代码示例

第一步:启动类加注解

复制代码
@SpringBootApplication
@EnableScheduling  // ← 开启定时任务
public class SkyApplication {
    public static void main(String[] args) {
        SpringApplication.run(SkyApplication.class, args);
    }
}

第二步:编写定时任务类

复制代码
@Component
@Slf4j
public class MyTask {

    /**
     * 每5秒执行一次(固定速率)
     */
    @Scheduled(fixedRate = 5000)
    public void fixedRateTask() {
        log.info("fixedRate 任务执行:{}", LocalDateTime.now());
    }

    /**
     * 每天凌晨1点执行(Cron)
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void dailyTask() {
        log.info("每日定时任务执行");
        // 实际业务:清理过期数据、生成报表等
    }

    /**
     * 每10秒执行一次(固定延迟)
     */
    @Scheduled(fixedDelay = 10000)
    public void fixedDelayTask() {
        log.info("fixedDelay 任务执行:{}", LocalDateTime.now());
    }
}

六、苍穹外卖中的实际应用场景 🍔

结合项目,Spring Task 的典型用法:

场景1:定时清理过期订单

复制代码
/**
 * 每分钟检查一次,自动取消超时未支付的订单
 */
@Scheduled(cron = "0 0/1 * * * ?")  // 每1分钟执行
public void cancelTimeoutOrders() {
    // 查询超过15分钟未支付的订单
    // 将其状态改为「已取消」
    log.info("自动取消超时订单...");
}

场景2:定时处理「已完成」的订单

复制代码
/**
 * 每天凌晨2点,将前一天已完成的订单做数据统计
 */
@Scheduled(cron = "0 0 2 * * ?")
public void processCompletedOrders() {
    // 统计营业额、清理临时数据等
    log.info("处理已完成订单数据...");
}

场景3:定时推送营业提醒

复制代码
/**
 * 每天早上9点推送营业提醒
 */
@Scheduled(cron = "0 0 9 * * ?")
public void sendOpenReminder() {
    // 推送消息给商家
    log.info("发送营业提醒...");
}

七、注意事项 ⚠️

要点 说明
单线程执行 默认所有 @Scheduled 任务共用一个线程,任务多了会排队
方法必须是 void @Scheduled 注解的方法不能有返回值
方法不能有参数 定时任务方法不支持传参
类需被 Spring 管理 任务类要加 @Component 等注解
分布式慎用 单机没问题,集群部署时需要配合 Redis 分布式锁 ​ 或 XXL-Job

🚀 多线程优化(进阶)

如果任务多了需要并行执行,可以配置线程池:

复制代码
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setTaskScheduler(taskScheduler());
    }

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5);  // 5个线程
        scheduler.setThreadNamePrefix("scheduled-task-");
        return scheduler;
    }
}

八、总结脑图

复制代码
Spring Task
├── 核心注解
│   ├── @EnableScheduling(开启)
│   └── @Scheduled(标记方法)
├── 三种方式
│   ├── fixedDelay → 上次结束后间隔
│   ├── fixedRate  → 固定频率
│   └── cron        → 灵活时间(最常用)
├── Cron 表达式
│   ├── 6个字段:秒 分 时 日 月 周
│   └── 通配符:* ? - , / L W
└── 注意事项
    ├── 默认单线程
    ├── 方法无参无返回值
    └── 集群需配合分布式锁

好啦!本期的学习到此结束,我们下期再见!!!

相关推荐
莫陌尛.2 小时前
etcd与Nacos功能及场景对比文档
java
麻瓜code2 小时前
【JUC】并发容器:从线程不安全到阻塞队列
java
许彰午3 小时前
50-18个表单控件
java·低代码·架构
白宇横流学长3 小时前
基于springboot的个人博客系统的设计与实现【源码+文档】
java·spring boot
白远山4 小时前
本地游戏代练源码开发实战:架构设计与核心功能实现指南
java·开发语言·架构·需求分析
wno7044 小时前
Spring Security添加图形验证码
java·后端·spring
曹牧4 小时前
Postman:`Content-Type` 和 `charset`
java
逆境不可逃4 小时前
Pi Agent 学习笔记:扩展如何介入工具调用
java
用户094248568034 小时前
第12章:JDK 诊断工具箱——jps / jstat / jmap / jcmd / jhsdb
java·jvm