依赖
org.quartz-scheduler
quartz
2.3.2
org.quartz-scheduler
quartz-jobs
2.3.2
或:
org.springframework.boot
spring-boot-starter-quartz
YML配置
spring:
quartz:
job-store-type: JDBC
jdbc:
initialize-schema: ALWAYS #NEVER ,ALWAYS会自动初始化数据库
properties:
org:
quartz:
overwrite-existing-jobs: true
scheduler:
instanceName: clusteredScheduler #调度标识名 集群中每一个实例都必须使用相同的名称
instanceId: AUTO #ID设置为自动获取 每一个必须不同
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX #数据保存方式为持久化
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #数据库平台
tablePrefix: QRTZ_ #表的前缀
isClustered: true #是否加入集群(集群时,一个任务只有一个服务实例执行)
clusterCheckinInterval: 10000 #调度实例失效的检查时间间隔
useProperties: false
misfireThreshold: 1000 # 容许的最大作业延长时间ms,该时间内错过的任务重启服务时会被补偿
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10 #线程数量
threadPriority: 9 #线程优先级
threadsInheritContextClassLoaderOfInitializingThread: true #自创建父线程
data-source:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/xxxx?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=round&serverTimezone=Asia/Shanghai
username: root
password: root
固定任务
@Configuration
public class HelloJobConfig {
//quartz数据库设置连接池
@Bean
@QuartzDataSource//quartz专用注解
@ConfigurationProperties(prefix = "spring.quartz.data-source")
public DataSource quartzDataSource(){
return new HikariDataSource();
}
@Bean
public JobDetail helloJobDetail() {
return JobBuilder.newJob(HelloJob.class)
.withIdentity("jobDetailName", "jobDetailGroup")
.usingJobData("userName", "zhangsan")//参数
.storeDurably()
.build();
}
@Bean
public Trigger helloJobTrigger()
{
//每隔5秒执行一次
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
//创建触发器
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(helloJobDetail())//关联上述的JobDetail
.withIdentity("triggerName","triggerGroup")//给Trigger起个名字
.withSchedule(cronScheduleBuilder)
.build();
return trigger;
}
}
通过接口添加删除更新自定义任务的触发器
(以用户自定义闹钟模拟)
1) 添加闹钟
public void addTime(AddFoodRemindDto dto) throws SchedulerException {
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("deviceId", dto.getDeviceId());
jobDataMap.put("time", dto.getTime());
jobDataMap.put("userId", dto.getUserId());
String jobName = dto.getUserId() + "_" + dto.getTime();
String jobGroup = FoodRemindJob.NAME_SPACE;
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
Trigger checkExist = scheduler.getTrigger(triggerKey);
if (checkExist == null) {
JobDetail jobDetail = JobBuilder.newJob(FoodRemindJob.class)
.requestRecovery(false)
.usingJobData(jobDataMap)
.withIdentity(jobName, jobGroup)
.storeDurably(true)
.build();
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(getCronByTime(dto.getTime()))
.withMisfireHandlingInstructionDoNothing();
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName, jobGroup)
.withSchedule(cronScheduleBuilder)
.build();
scheduler.scheduleJob(jobDetail, trigger);
}
}
private String getCronByTime(String time) {
String model = "0 {0} {1} * * ?";
String[] split = time.split(":");
return MessageFormat.format(model, split[1], split[0]);
}
2) 删除闹钟
public void deleteTime(DeleteFoodRemindDto dto) throws SchedulerException {
String jobName = dto.getUserId() + "_" + dto.getTime();
String jobGroup = FoodRemindJob.NAME_SPACE;
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
Trigger checkExist = scheduler.getTrigger(triggerKey);
if (checkExist != null) {
scheduler.unscheduleJob(triggerKey);
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
}
}
3)工具方法
//创建job
public void createJob(Scheduler scheduler, Class extends Job> jobClass, String jobName, String jobGroup, String cron, Map param) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(jobClass)
.withIdentity(jobName, jobGroup)
.build();
if (param != null && !param.isEmpty()) {
param.forEach((key, value) -> jobDetail.getJobDataMap().put(key, value));
}
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
CronTrigger build = TriggerBuilder.newTrigger()
.withIdentity(jobName, jobGroup).withSchedule(scheduleBuilder)
.build();
scheduler.scheduleJob(jobDetail, build);
}
//刷新job
public void refreshJob(Scheduler scheduler, String jobName, String jobGroup, String cron) throws SchedulerException {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
CronTrigger build = TriggerBuilder.newTrigger()
.withIdentity(jobName, jobGroup).withSchedule(scheduleBuilder)
.build();
scheduler.rescheduleJob(triggerKey, build);
}
//恢复job
public void resumeJob(Scheduler scheduler, String jobName, String jobGroup) throws SchedulerException {
scheduler.resumeJob(JobKey.jobKey(jobName, jobGroup));
}
//暂停job
public void pauseJob(Scheduler scheduler, String jobName, String jobGroup) throws SchedulerException {
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroup));
}
//删除job
public void deleteJob(Scheduler scheduler, String jobName, String jobGroup) throws SchedulerException {
scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroup));
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
}