当前位置: 首页 > java >正文

Spring Boot定时任务

在 Spring Boot 中实现定时任务主要依赖于@Scheduled注解和 Spring 调度器。

基本概念


定时任务,简单来说就是在特定的时间点或按照一定的时间间隔自动执行的任务。在 Spring Boot 中,实现定时任务主要依赖于 Spring 框架提供的 @Scheduled 注解和 TaskScheduler 接口。@Scheduled 注解可以方便地将一个方法标记为定时执行的任务,而 TaskScheduler 则负责任务的调度和执行。

Cron是一个字符串,由7个字段组成,使用空格隔开 ,用于指定定时任务的执行时间。也称为七子表达式

字段取值范围说明
0-59*/10
0-59
0-236-16
1-31
1-12
星期0-70和7都表示星期日
1970~2099此项非必需,可以省略

使用以下特殊字符来指定执行时间:

  • 星号(*):表示匹配该字段的所有可能值

  • 问号(?):表示不关心该字段具体的值

  • 斜线(/):表示指定一个间隔

  • 逗号(,):表示列举多个值

  • 连字符(-):表示指定一个范围

Cron表达式在线生成器:在线Cron表达式生成器

一、定时任务核心实现

1. 核心注解与配置
  • @Scheduled:标记方法为定时任务,支持多种触发方式(Cron、固定速率 / 延迟等)。
  • @EnableScheduling:在启动类中启用定时任务功能。
  • 线程池配置:默认单线程,建议通过ThreadPoolTaskScheduler配置多线程。
@SpringBootApplication
@EnableScheduling // 启用定时任务
public class RuoYiApplication {public static void main(String[] args) {SpringApplication.run(RuoYiApplication.class, args);}
}@Component
public class AttendanceCheckTask {@Autowiredprivate ISysDeptService sysDeptService;// 每天18点10分执行(Cron表达式)@Scheduled(cron = "0 10 18 * * ?")public void checkMonthlyAttendance() {// 任务逻辑}
}
2. Cron 表达式详解
  • 结构秒 分 时 日 月 周(共 6 个字段)。
  • 示例
    • 0 0 1 * * ?:每天凌晨 1 点。
    • 0 30 8 ? * 1-5:工作日早上 8:30。
    • 0 0 0 1 * ?:每月 1 号 0 点。
3. 线程池配置
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {@Overridepublic void configureTasks(ScheduledTaskRegistrar registrar) {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(10); // 线程池大小scheduler.setThreadNamePrefix("Attendance-Scheduler-");registrar.setTaskScheduler(scheduler);}
}

二、用户代码实现分析

1. 核心业务逻辑
@Component
public class AttendanceCheckTask {@Autowiredprivate IAttendanceRecordService attendanceRecordService;@Autowiredprivate ISysNoticesService sysNoticesService;@Autowiredprivate ISysUserService sysUserService;@Autowiredprivate ISysDeptService sysDeptService;@Scheduled(cron = "0 10 18 * * ?")public void checkMonthlyAttendance() {// 1. 获取上月考勤数据List<Map<String, Object>> userList = attendanceRecordService.selectUsersWithNormalDaysLastMonth();// 2. 遍历生成公告for (Map<String, Object> user : userList) {Long userId = (Long) user.get("userId");Integer normalDays = ((Long) user.get("normalDays")).intValue();// 3. 查询用户和部门信息SysUser sysUser = sysUserService.selectUserById(userId);if (sysUser == null) {logger.warn("用户ID {} 不存在,跳过", userId);continue;}String deptName = sysDeptService.selectDeptById(sysUser.getDeptId()).getDeptName();String userName = sysUser.getNickName();// 4. 生成公告内容String noticeContent = String.format("🎉 %s 部门的 %s 同志,在上月以 **%d 天全勤** 表现优异!\n" +"你的坚持是团队的榜样,继续加油!",deptName, userName, normalDays);// 5. 保存公告saveNotice(noticeContent);}}private void saveNotice(String content) {SysNotices notice = new SysNotices();notice.setNoticeTitle("月度全勤标兵表彰");notice.setNoticeType("2");notice.setNoticeContent(content);notice.setStatus("0");notice.setCreateBy("system");sysNoticesService.insertSysNotices(notice);}
}
2. 关键技术点
  • 部门名称获取:通过ISysDeptService查询部门信息。
  • 用户昵称获取:通过ISysUserService查询用户昵称。
  • 公告内容优化:使用部门名称和用户昵称替代用户 ID。

三、高级特性与优化

1. 动态调整 Cron 表达式
@Configuration
public class DynamicCronConfig implements SchedulingConfigurer {private volatile String cronExpression = "0 10 18 * * ?";@Overridepublic void configureTasks(ScheduledTaskRegistrar registrar) {registrar.addTriggerTask(this::checkMonthlyAttendance,triggerContext -> {CronTrigger trigger = new CronTrigger(cronExpression);return trigger.nextExecutionTime(triggerContext);});}// 通过API或配置中心修改cronExpressionpublic void updateCron(String newCron) {this.cronExpression = newCron;}
}
2. 异常处理与重试
@Component
public class AttendanceCheckTask {private static final Logger logger = LoggerFactory.getLogger(AttendanceCheckTask.class);@Scheduled(cron = "0 10 18 * * ?")public void checkMonthlyAttendance() {try {// 核心逻辑} catch (Exception e) {logger.error("定时任务执行失败:", e);// 重试逻辑(如调用Feign接口触发重试)}}
}

 3. 分布式定时任务方案

  • XXL-JOB:可视化管理界面,支持分布式调度
// 引入依赖
<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.3.1</version>
</dependency>// 配置执行器
@Component
public class XxlJobConfig {@Beanpublic XxlJobSpringExecutor xxlJobExecutor() {XxlJobSpringExecutor executor = new XxlJobSpringExecutor();executor.setAdminAddresses("http://xxl-job-admin:8080/xxl-job-admin");executor.setAppname("ruoyi-attendance");executor.setAddress("");return executor;}
}// 定义任务
@XxlJob("attendanceCheckJob")
public ReturnT<String> execute(String param) {// 任务逻辑return ReturnT.SUCCESS;
}

四、最佳实践与注意事项

  1. 线程安全:避免在任务中修改共享状态,必要时使用@Async异步处理。
  2. 数据库优化
    • 为考勤查询添加索引:ALTER TABLE attendance_record ADD INDEX idx_month (user_id, year, month);
    • 分页查询:selectUsersWithNormalDaysLastMonth方法添加分页参数。
  3. 监控与日志
    • 集成 Spring Boot Actuator:management.endpoints.web.exposure.include=health,info,scheduledtasks
    • 日志记录:在任务开始和结束时记录关键信息。
  4. 性能调优
    • 使用缓存:将部门和用户信息缓存到 Redis。
    • 异步处理:将公告生成和保存逻辑异步化。

五、总结

Spring Boot 的定时任务实现简单高效,通过@Scheduled注解和线程池配置即可满足大部分需求。对于复杂场景(如分布式调度、动态配置),可结合 XXL-JOB 等框架扩展。在实际开发中,需注意线程安全、数据库性能和异常处理,确保任务稳定可靠运行。

http://www.xdnf.cn/news/2662.html

相关文章:

  • 深入浅出JavaScript常见设计模式:从原理到实战(2)
  • 一文读懂Tomcat应用之 CentOS安装部署Tomcat服务
  • rabbitmq-集群部署
  • 当所有人都用上先进ai,如何保持你的优势?
  • 用Postman验证IAM Token的实际操作
  • Error和Exception的区别
  • 第9讲:坐标轴美学深度优化——刻度线、网格线与边框控制
  • mapbox V3 新特性,室内楼层多层同时三维展示(可单层切换),类似蜂鸟视图效果
  • 深度学习任务评估指标
  • 从普查到防控:ArcGIS洪水灾害全流程分析技术实战——十大专题覆盖风险区划/淹没制图/水文分析/洪水分析/淹没分析/项目交流,攻克防洪决策数据瓶颈!
  • QT:自定义ComboBox
  • 自动驾驶领域专业词汇(专业术语)整理
  • leetcode 206. 反转链表
  • 湖北理元理律师事务所:债务管理领域的平台化创新探索
  • 回归预测 | Matlab实现DBO-LightGBM蜣螂算法优化轻量级梯度提升机多输入单输出回归预测,作者:机器学习之心
  • 嵌入式开发面试典型编程题解析:排序算法、指针操作、字符处理、递归原理等基础原理的深度解析。
  • 第33周JavaSpringCloud微服务 分布式综合应用
  • echarts+标签+指引线
  • 【javascript】竞速游戏前端优化:高频操作与并发请求的解决方案
  • 开源模型应用落地-全能音频新纪元-Kimi-Audio-7B-Instruct-重塑多模态交互边界
  • Transformer数学推导——Q29 推导语音识别中流式注意力(Streaming Attention)的延迟约束优化
  • 核心要点:线程
  • 解决MacOS端口被占用问题
  • 升级xcode15 报错Error (Xcode): Cycle inside Runner
  • Visual Studio 技能:调整软件界面布局
  • 区块链vs实体经济:一场金融、医疗、政务与物流的“效率革命”
  • C++——入门基础
  • 人工智能大语言模型与AI芯片新进展:技术演进与商业化路径
  • 防火墙拦截DNS请求-原理解析
  • 如何快速在idea中希望Spark程序