1、Spring 定时任务
定时任务(Scheduled Task)指的是按照指定的时间或时间间隔,自动执行的任务。
在应用程序中通常用于自动化处理一些定期或周期性的操作,特别是与时间相关的任务。
应用场景:
- 数据统计与报表生成
- 缓存清理与刷新:自动清理过期数据
- 数据同步与备份
- 系统监控与告警
- 消息发送与通知:自动发送邮件
1.1 执行方式
-
固定间隔执行
- 使用
fixedRate或fixedDelay fixedRate: 每隔固定时间执行一次(开始时间到开始时间)fixedDelay: 上一次任务完成后延迟固定时间再执行
- 使用
-
Cron 表达式执行
- 使用
cron表达式,可以精确控制执行时间(每天、每周、每月等) - 表达式格式:
秒 分 时 日 月 星期
- 使用
-
触发器任务
- Spring 还支持基于触发器(Trigger)的复杂任务调度,可以动态控制下次执行时间
2、定时任务 Spring Task 实现
2.1 开启定时任务
引入 Spring 的定时任务依赖:Spring Boot 中启用定时任务添加 @EnableScheduling 注解
@SpringBootApplication
@MapperScan("com.hospital.mapper")
@EnableCaching
@EnableScheduling // 开启定时任务
public class SpringBootSystemApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSystemApplication.class, args);
}
}
2.2 创建定时任务类
使用 @Scheduled 注解来定义执行周期和任务,创建AppointmentTask,实现自动取消过期预约
package com.example.task;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.example.entity.Appointment;
import com.example.mapper.AppointmentMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
@Slf4j
@Component
public class AppointmentTask {
@Autowired
private AppointmentMapper appointmentMapper;
/**
* 每天凌晨1点执行,将已过期未就诊的预约状态改为"已过期"
* cron表达式:秒 分 时 日 月 星期
*/
@Scheduled(cron = "0 0 1 * * ?")
public void cancelExpiredAppointments() {
log.info("开始执行过期预约取消任务");
// 获取当前日期之前的所有预约(预约日期小于今天)
Date today = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
LambdaUpdateWrapper<Appointment> wrapper = new LambdaUpdateWrapper<>();
wrapper.lt(Appointment::getAppointmentDate, today)
.eq(Appointment::getStatus, "已预约")
.set(Appointment::getStatus, "已过期");
int rows = appointmentMapper.update(null, wrapper);
log.info("过期预约取消任务完成,共更新{}条记录", rows);
}
/**
* 测试用:每30秒执行一次(取消后注释)
*/
// @Scheduled(fixedDelay = 30000)
// public void testTask() {
// log.info("定时任务测试");
// }
}