在实际开发中,动态定时任务的需求非常常见。本文将介绍如何通过SpringBoot结合Quartz实现一个可以从数据库读取执行时间并动态调整的定时任务。
maven依赖配置
首先,确保项目中引入了以下Maven依赖:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
核心代码实现
1. 定时任务类
创建一个简单的任务类用于测试输出:
import org.quartz.JobExecutionException;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class TaskExecutor {
public void runTask() throws JobExecutionException {
System.out.println("任务正在运行...");
}
}
2. Quartz配置类
定义Quartz相关的配置类,包括任务详情和触发器:
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfig {
@Bean
public JobDetailFactoryBean jobDetail(TaskExecutor taskExecutor) {
JobDetailFactoryBean jobDetail = new JobDetailFactoryBean();
jobDetail.setJobClass(TaskExecutor.class);
jobDetail.setName("dynamic-task");
jobDetail.setGroup("task-group");
jobDetail.setDurability(true);
return jobDetail;
}
@Bean
public CronTrigger cronTrigger(JobDetail jobDetail) {
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/5 * * * ?");
CronTrigger trigger = new CronTrigger();
trigger.setJobDetail(jobDetail);
trigger.setCronExpression(scheduleBuilder.getCronExpression());
return trigger;
}
@Bean
public SchedulerFactoryBean schedulerFactory(CronTrigger cronTrigger) {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setTriggers(cronTrigger);
factory.setOverwriteExistingJobs(true);
factory.setStartupDelay(5);
return factory;
}
}
3. 动态刷新任务类
创建一个定时任务,定期从数据库中读取最新的cron表达式,并更新当前的任务计划:
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class DynamicTaskUpdater {
@Autowired
private Scheduler scheduler;
@Scheduled(fixedRate = 10000)
public void updateTaskSchedule() throws Exception {
// 模拟从数据库获取新的cron表达式
String newCron = "0 0/3 * * * ?"; // 示例:每3分钟执行一次
JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey("dynamic-task", "task-group"));
CronTrigger existingTrigger = (CronTrigger) scheduler.getTrigger(TriggerKey.triggerKey("dynamic-task", "task-group"));
if (!existingTrigger.getCronExpression().equals(newCron)) {
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(newCron);
CronTrigger updatedTrigger = TriggerBuilder.newTrigger()
.withIdentity("dynamic-task", "task-group")
.withSchedule(scheduleBuilder)
.build();
scheduler.rescheduleJob(existingTrigger.getKey(), updatedTrigger);
}
}
}
注意事项
- 确保`DynamicTaskUpdater`中的数据库查询逻辑正确无误。
- 根据实际需求调整`@Scheduled`的频率以及默认的cron表达式。
以上就是使用SpringBoot和Quartz实现动态定时任务的完整过程。