在 Spring Boot 中,实现定时任务非常简单,主要依赖于 Spring 的 @Scheduled
注解和任务调度框架。以下是实现定时任务的几种常见方式:
1. 使用 @Scheduled
注解
@Scheduled
是 Spring 提供的一个注解,用于标记需要定时执行的方法。可以通过配置 cron
表达式、固定延迟或固定速率来定义任务的执行时间。
实现步骤:
- 在主类或配置类上添加
@EnableScheduling
注解,启用定时任务支持。 - 在需要定时执行的方法上添加
@Scheduled
注解。
示例代码:
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@EnableScheduling
public class MyScheduledTasks {
// 每 5 秒执行一次
@Scheduled(fixedRate = 5000)
public void taskWithFixedRate() {
System.out.println("Fixed Rate Task: " + System.currentTimeMillis());
}
// 每次任务结束后延迟 3 秒执行
@Scheduled(fixedDelay = 3000)
public void taskWithFixedDelay() {
System.out.println("Fixed Delay Task: " + System.currentTimeMillis());
}
// 使用 cron 表达式,每分钟的第 30 秒执行
@Scheduled(cron = "30 * * * * ?")
public void taskWithCronExpression() {
System.out.println("Cron Task: " + System.currentTimeMillis());
}
}
参数说明:
fixedRate
:固定速率,单位毫秒。任务开始后,每隔指定时间执行一次。fixedDelay
:固定延迟,单位毫秒。任务结束后,延迟指定时间再执行下一次。cron
:Cron 表达式,用于定义复杂的调度规则。
Cron 表达式:
Cron 表达式由 6 或 7 个字段组成,格式为:秒 分 时 日 月 周 年(可选)
。例如:
0 * * * * ?
:每分钟的第 0 秒执行。0 0 12 * * ?
:每天中午 12 点执行。
2. 动态配置定时任务
如果需要动态调整定时任务的执行时间,可以通过编程方式实现。
实现步骤:
- 使用
ScheduledTaskRegistrar
注册定时任务。 - 通过自定义逻辑动态调整任务的执行时间。
示例代码:
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.util.concurrent.atomic.AtomicInteger;
@Component
@EnableScheduling
public class DynamicScheduledTask implements SchedulingConfigurer {
private final AtomicInteger counter = new AtomicInteger(0);
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
() -> {
System.out.println("Dynamic Task: " + System.currentTimeMillis());
counter.incrementAndGet();
},
triggerContext -> {
// 动态调整 cron 表达式
String cron = "0/" + counter.get() + " * * * * ?";
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
}
3. 使用 TaskScheduler
Spring 提供了 TaskScheduler
接口,可以通过编程方式调度任务。
示例代码:
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.ScheduledFuture;
@Component
public class MyTaskScheduler {
private final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
private ScheduledFuture<?> future;
@PostConstruct
public void init() {
taskScheduler.initialize();
// 每 10 秒执行一次
future = taskScheduler.schedule(
() -> System.out.println("TaskScheduler Task: " + System.currentTimeMillis()),
new CronTrigger("0/10 * * * * ?")
);
}
public void cancelTask() {
if (future != null) {
future.cancel(true);
}
}
}
4. 使用 Quartz 调度框架
如果需要更强大的调度功能(如持久化任务、集群支持等),可以集成 Quartz 调度框架。
实现步骤:
- 添加 Quartz 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
- 配置 Quartz 任务和触发器。
- 使用
Scheduler
调度任务。
示例代码:
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
@Bean
public JobDetail jobDetail() {
return JobBuilder.newJob(MyJob.class)
.withIdentity("myJob")
.storeDurably()
.build();
}
@Bean
public Trigger trigger() {
return TriggerBuilder.newTrigger()
.forJob(jobDetail())
.withIdentity("myTrigger")
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
}
}
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Quartz Job: " + System.currentTimeMillis());
}
}
5. 多线程定时任务
默认情况下,Spring 的定时任务是单线程执行的。如果需要并发执行任务,可以配置线程池。
示例代码:
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 scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5); // 设置线程池大小
scheduler.setThreadNamePrefix("ScheduledTask-");
return scheduler;
}
}
总结
在 Spring Boot 中实现定时任务的方式包括:
- 使用
@Scheduled
注解(适合简单任务)。 - 动态配置定时任务(适合需要动态调整的任务)。
- 使用
TaskScheduler
(适合编程式调度)。 - 使用 Quartz 框架(适合复杂调度需求)。
- 配置多线程定时任务(适合并发执行任务)。
根据具体需求选择合适的方式,可以轻松实现定时任务功能。
THE END
暂无评论内容