我们在写Java程序中经常会写一些定时执行的任务,例如每天执行一次什么方法,几分钟或者几个小时调用一次存储过程等等
Quartz的三个核心概念:
任务:执行工作的内容,Quartz提供job接口来支持任务定义
触发器:定义触发job执行的事件触发规则,Quartz提供Trigger类及其子类支持触发功能
调度器:Quartz提供Scheduler接口,将工作任务和触发器绑定,保证任务可以在正确的时间执行
引用依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.5</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
创建任务:
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
/**
* demo任务
*/
public class DemoJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("任务已执行...");
}
}
编写JobDetailDTO和TriggerDTO用来分别传输定时任务作业细节和触发器的配置内容
import lombok.Data;
import java.util.Map;
/**
* 任务细节构造传输实体
*/
@Data
public class JobDetailDTO {
/**
* 任务细节名称
*/
private String jobDetailName;
/**
* 组名称
*/
private String groupName;
/**
* 任务类
*/
private Class jobClass;
/**
* 任务数据
*/
private Map<String, Object> jobDataMap;
}
import lombok.Data;
import java.util.Map;
/**
* 触发器构造传输实体
*/
@Data
public class TriggerDTO {
/**
* 触发器名称
*/
private String triggerName;
/**
* 组名称
*/
private String groupName;
/**
* 执行计划开始时间
*/
private String startDay;
/**
* 执行计划结束时间
*/
private String endDay;
/**
* 执行计划表达式
*/
private String cronExpress;
/**
* 任务数据
*/
private Map<String, Object> jobDataMap;
}
调度任务:为了调度此任务执行,需要先得到一个Schedule实例,然后创建一个包含任务信息的JobDetail,最后创建一个Trigger管理任务的执行。这里编写一个任务工厂来管理任务的各组件的构造。
import cn.hutool.core.collection.CollectionUtil;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
/**
* Quartz定时任务工厂类
*/
public class QuartzFactory {
private static Scheduler scheduler;
private QuartzFactory() {
}
static {
try {
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 获取调度器
*
* @return
*/
public static Scheduler getScheduler() {
return scheduler;
}
/**
* 获取触发器
*
* @param dto
* @return
*/
public static Trigger getTrigger(TriggerDTO dto) {
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(dto.getTriggerName(), dto.getGroupName())
.withSchedule(CronScheduleBuilder.cronSchedule(dto.getCronExpress()))
.build();
if (CollectionUtil.isNotEmpty(dto.getJobDataMap())) {
dto.getJobDataMap().forEach((s, o) -> trigger.getJobDataMap().put(s, o));
}
return trigger;
}
/**
* 获取任务细节
*
* @param dto
* @return
*/
public static JobDetail getJobDetail(JobDetailDTO dto) {
JobDetail jobDetail = JobBuilder.newJob(dto.getJobClass())
.withIdentity(dto.getJobDetailName(), dto.getGroupName())
.build();
if (CollectionUtil.isNotEmpty(dto.getJobDataMap())) {
dto.getJobDataMap().forEach((s, o) -> jobDetail.getJobDataMap().put(s, o));
}
return jobDetail;
}
public static void main(String[] args) throws SchedulerException {
JobDetailDTO jobDetailDTO = new JobDetailDTO();
jobDetailDTO.setJobDetailName("first-job");
jobDetailDTO.setGroupName("default");
jobDetailDTO.setJobClass(DemoJob.class);
TriggerDTO triggerDTO = new TriggerDTO();
triggerDTO.setTriggerName("first-trigger");
triggerDTO.setGroupName("default");
triggerDTO.setCronExpress("*/5 * * * * ?");
Scheduler scheduler = QuartzFactory.getScheduler();
Trigger trigger = QuartzFactory.getTrigger(triggerDTO);
JobDetail jobDetail = QuartzFactory.getJobDetail(jobDetailDTO);
scheduler.scheduleJob(jobDetail, trigger);
}
}