一、什么是定时任务
定时任务是指在 特定时间点 或 时间间隔 执行的任务。在实际项目中,我们经常需要定时执行一些操作,比如:
- 定时清理临时文件
- 定时更新缓存
- 定时生成报表
- 定时检查状态并更新
二、在SSM项目中实现定时任务
2.1 添加依赖
首先在pom.xml
中添加Spring Task
相关依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>6.1.12</version>
</dependency>
2.2 配置定时任务支持
在Spring配置文件(如spring-mybatis.xml)中添加task命名空间和注解驱动:
<!-- 添加task命名空间 -->
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
...
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd"
<!-- 开启注解驱动 -->
<task:annotation-driven/>
2.3 创建定时任务配置类【可选】
@Configuration
@EnableScheduling
public class TaskConfig {
/**
* 配置定时任务线程池
* 默认情况下,Spring使用单线程执行定时任务
* 通过配置线程池可以实现多个任务并行执行
*/
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
// 设置线程池大小
scheduler.setPoolSize(5);
// 设置线程名前缀
scheduler.setThreadNamePrefix("task-");
// 等待所有任务完成再关闭线程池
scheduler.setWaitForTasksToCompleteOnShutdown(true);
// 设置等待时间
scheduler.setAwaitTerminationSeconds(60);
return scheduler;
}
}
2.4 创建定时任务处理类
@Component
@Slf4j
public class EventStatusTask {
private final EventMapper eventMapper;
@Scheduled(cron = "0 */5 * * * *")
public void updateExpiredEventStatus() {
try {
int count = eventMapper.updateExpiredEventStatus();
if (count > 0) {
log.info("成功更新{}个过期事件状态", count);
}
} catch (Exception e) {
log.error("更新过期事件状态失败", e);
}
}
}
三、Cron表达式详解
Cron表达式是一个字符串,包含6或7个域,用空格分隔,每个域代表一个含义
秒 分 时 日 月 周 [年]
0 0 9 12 10 ? 2024
2024年10月12日上午9点整 对应的cron表达式为:0 0 9 12 10 ? 2024
常用示例:
0 */5 * * * *
: 每5分钟执行一次0 0 * * * *
: 每小时整点执行0 0 0 * * *
: 每天凌晨执行0 0 9,18 * * *
: 每天上午9点和下午6点执行0 0/30 9-17 * * *
: 朝九晚五工作时间内每半小时执行
特殊字符说明:
*
: 表示所有值/
: 表示增量值-
: 表示范围,
: 表示多个值?
: 用于日期和星期字段,表示不指定具体值
这Cron表达式的语法简单记忆一下就行,现在很多工具可以帮助我们快速生成这个Cron表达式
例如:在线Corn表达式生成器
四、在SpringBoot中实现定时任务
SpringBoot中实现定时任务更加简单,主要有以下步骤:
4.1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
4.2 开启定时任务
在启动类上添加@EnableScheduling注解:
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4.3 创建定时任务
@Component
@Slf4j
public class TaskService {
@Scheduled(cron = "0 */5 * * * *")
public void scheduledTask() {
log.info("定时任务执行...");
}
// 固定延迟执行,上一次执行完成后延迟5秒
@Scheduled(fixedDelay = 5000)
public void fixedDelayTask() {
log.info("固定延迟任务");
}
// 固定频率执行,每5秒执行一次
@Scheduled(fixedRate = 5000)
public void fixedRateTask() {
log.info("固定频率任务");
}
}
五、最佳实践建议
- 合理设置执行频率,避免任务执行时间过长影响系统性能
- 添加
try-catch
异常处理,避免任务异常影响其他功能 - 添加日志记录,方便追踪任务执行情况
- 对于重要任务考虑添加执行结果通知机制
- 在分布式系统中需要考虑任务重复执行问题
- 对于耗时任务考虑使用异步执行
六、总结
无论是 SSM 还是 SpringBoot 项目,Spring 框架都为我们提供了便捷的定时任务实现方式。相比之下,SpringBoot的配置更加简单,但核心概念是一致的。在实际应用中,我们需要根据具体需求选择合适的执行方式,并注意性能和异常处理等问题。