Spring Task 使用指南
标签
SpringBoot
Cron
Framework
字数
896 字
阅读时间
5 分钟
1 简介
Spring Task 是 Spring 提供的任务调度模块,用于在指定时间或间隔执行方法。它支持使用简单的时间间隔、固定延迟以及Cron表达式进行任务调度。
2 依赖配置
[!ttip] Spring Task 依赖
spring-context
包含于spring-boot-starter
在使用Spring Task之前,需要在项目中添加相关依赖。对于Maven项目,编辑 pom.xml
并添加以下依赖:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
对于Gradle项目,编辑 build.gradle
并添加以下依赖:
groovy
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
3 启用任务调度
在Spring Boot应用中,可以在主应用类或配置类上使用 @EnableScheduling
注解来启用任务调度功能。
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4 使用@Scheduled注解
@Scheduled
注解用于定义任务调度的方法。它可以使用固定速率、固定延迟或Cron表达式来调度任务。
java
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
// 每隔5秒执行一次
@Scheduled(fixedRate = 5000)
public void fixedRateTask() {
System.out.println("Fixed rate task - " + System.currentTimeMillis() / 1000);
}
// 上次任务完成后5秒再执行
@Scheduled(fixedDelay = 5000)
public void fixedDelayTask() {
System.out.println("Fixed delay task - " + System.currentTimeMillis() / 1000);
}
// 第一次延迟1秒后执行,之后每5秒执行一次
@Scheduled(initialDelay = 1000, fixedRate = 5000)
public void initialDelayTask() {
System.out.println("Initial delay task - " + System.currentTimeMillis() / 1000);
}
// 使用Cron表达式调度
@Scheduled(cron = "0 * * * * ?")
public void cronTask() {
System.out.println("Cron task - " + System.currentTimeMillis() / 1000);
}
}
5 Cron 表达式
Cron表达式用于定义复杂的调度规则,格式如下:
second minute hour day-of-month month day-of-week
5.1 示例
0 0 * * * ?
每小时整点执行0 0 12 * * ?
每天中午12点执行0 0 12 * * MON-FRI
每周一到周五的中午12点执行
6 配置任务调度线程池
默认情况下,Spring使用单线程执行所有任务。可以通过配置线程池来提高并发处理能力。
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
public class SchedulerConfig {
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
taskScheduler.setThreadNamePrefix("Scheduled-Task-");
return taskScheduler;
}
}
7 示例
7.1 定时执行数据库备份
java
@Component
public class DatabaseBackupTask {
@Scheduled(cron = "0 0 2 * * ?")
public void backupDatabase() {
System.out.println("Database backup started at - " + new Date());
// 执行备份逻辑
}
}
7.2 定期清理临时文件
java
@Component
public class CleanupTask {
@Scheduled(fixedRate = 86400000) // 每天执行一次
public void cleanup() {
System.out.println("Cleanup task started at - " + new Date());
// 执行清理逻辑
}
}
8 调试和日志
可以通过日志记录来调试和监控任务的执行情况。建议使用SLF4J和Logback记录日志。
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class LoggingTask {
private static final Logger logger = LoggerFactory.getLogger(LoggingTask.class);
@Scheduled(cron = "0 * * * * ?")
public void logTask() {
logger.info("Log task executed at - {}", new Date());
}
}
9 常见问题
9.1 为什么我的@Scheduled方法没有执行?
- 确保使用了
@EnableScheduling
注解: 确保在配置类或主应用类上使用了@EnableScheduling
注解。 - 方法签名: 确保
@Scheduled
注解的方法是public
且没有参数。 - Cron表达式错误: 检查Cron表达式是否正确。
9.2 如何避免任务重叠执行?
可以使用分布式锁或数据库锁来避免任务重叠执行。也可以配置任务调度线程池,确保足够的线程资源。