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

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 等框架扩展。在实际开发中,需注意线程安全、数据库性能和异常处理,确保任务稳定可靠运行。

相关文章:

  • Sui 主网升级至 V1.47.1
  • Spring Boot 3与JDK 8环境下的单元测试实践指南
  • stm32week13
  • 蒋新松:中国机器人之父
  • 三小时快速上手TypeScript之枚举
  • 【知识科普】HTTPS 加密中信息的可见性详解
  • [密码学实战]SDF之设备管理类函数(一)
  • 智能物证管理系统|DW-S404全国广泛应用
  • 关系数据的可视化
  • tanstack动态路由 + router/ 目录管理方案
  • 数据分析1
  • 一文读懂Tomcat应用之 CentOS安装部署Tomcat服务
  • LabVIEW开发之困境中逼出成长力
  • 基于 Spring Boot 瑞吉外卖系统开发(八)
  • 如何在idea中写spark程序。
  • 工业通讯现场中关于EtherCAT转TCPIP网关的现场应用
  • 【爬虫】码上爬第1题:动态数据采集
  • 4月28日星期一今日早报简报微语报早读
  • Linux 内核网络协议栈中的关键数据结构:inet_skb_parm 与 ip_options
  • 软件设计师速通其一:计算机内部数据表示
  • 千亿市值光储龙头董事长向母校合肥工业大学捐赠1亿元
  • 金融创新破局记:中小微企业转型背后的金融力量
  • 清华成立人工智能医院,将构建“AI+医疗+教育+科研”闭环
  • 闲暇时间的“堕落”
  • 京东美团开打,苦了商家?
  • 泽连斯基与特朗普进行简短会谈