一、Quartz 简介
Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中。它提供了巨大的灵 活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB作业预构 建,JavaMail及其它,支持cron-like表达式等等。
二、引入 maven 依赖
<!-- Quartz 定时任务 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
三、编写代码
1、编写 Service 接口类
package com.cxy.job;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDataMap;
public interface SysQuartzService {
/**
* 添加定时任务
* @param name 任务名称
* @param iClass JOB类
* @param cron 表达式
* @param param 参数
*/
public void schedulerAdd(String name, Class<? extends Job> iClass, String cron, JobDataMap param);
/**
* 添加定时任务
* @param name 任务名称
* @param iClass JOB类
* @param cron 表达式
* @param startTime 开始时间 (选填)
* @param endTime 结束时间 (选填)
* @param param 参数
*/
public void schedulerAdd(String name, Class<? extends Job> iClass, String cron, Date startTime, Date endTime, JobDataMap param);
/**
* 添加定时任务
* @param name 任务名称
* @param iClass JOB类
* @param count 运行的次数 (-1 无限执行、n 执行次数,索引0开始)
* @param second 每次间隔的时间 (s)
* @param param 参数
*/
public void schedulerAdd(String name, Class<? extends Job> iClass, int count, int second, JobDataMap param);
/**
* 添加定时任务
* @param name 任务名称
* @param iClass JOB类
* @param count 运行的次数 (-1 无限执行、n 执行次数,索引0开始)
* @param second 每次间隔的时间 (s)
* @param startTime 开始时间 (选填)
* @param endTime 结束时间 (选填)
* @param param 参数
*/
public void schedulerAdd(String name, Class<? extends Job> iClass, int count, int second, Date startTime, Date endTime, JobDataMap param);
/**
* 删除定时任务
* @param name 任务名称
*/
public void schedulerDelete(String name);
}
2、编写 ServiceImpl 实现类
package com.cxy.job;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class SysQuartzServiceImpl implements SysQuartzService {
@Autowired
private Scheduler scheduler;
@Override
public void schedulerAdd(String name, Class<? extends Job> iClass, String cron, JobDataMap param) {
schedulerAdd(name, iClass, cron, null, null, param);
}
@Override
public void schedulerAdd(String name, Class<? extends Job> iClass, String cron, Date startTime, Date endTime, JobDataMap param) {
try {
// 删除旧任务
schedulerDelete(name);
// 启动调度器
scheduler.start();
// 构建job信息
JobDetail jobDetail = JobBuilder.newJob(iClass).withIdentity(name).setJobData(param).build();
// 表达式调度构建器(即任务执行的时间)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
// 按新的 cronExpression 表达式构建一个新的trigger
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder.withIdentity(name);
// 设置开始时间
if(startTime!=null) triggerBuilder.startAt(startTime);
// 设置结束时间
if(endTime!=null) triggerBuilder.endAt(endTime);
triggerBuilder.withSchedule(scheduleBuilder);
scheduler.scheduleJob(jobDetail, triggerBuilder.build());
} catch (SchedulerException e) {
log.error(e.getMessage());
} catch (RuntimeException e) {
log.error(e.getMessage());
} catch (Exception e) {
log.error(e.getMessage());
}
}
@Override
public void schedulerAdd(String name, Class<? extends Job> iClass, int count, int second, JobDataMap param) {
schedulerAdd(name, iClass, count, second, null, null, param);
}
@Override
public void schedulerAdd(String name, Class<? extends Job> iClass, int count, int second, Date startTime, Date endTime, JobDataMap param) {
try {
// 删除旧任务
schedulerDelete(name);
// 启动调度器
scheduler.start();
// 构建job信息
JobDetail jobDetail = JobBuilder.newJob(iClass).withIdentity(name).setJobData(param).build();
// 表达式调度构建器(即任务执行的时间)
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(second).withRepeatCount(count);
// 按新的cronExpression表达式构建一个新的trigger
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder.withIdentity(name);
triggerBuilder.withSchedule(scheduleBuilder);
// 设置开始时间
if(startTime!=null) triggerBuilder.startAt(startTime);
// 设置结束时间
if(endTime!=null) triggerBuilder.endAt(endTime);
scheduler.scheduleJob(jobDetail, triggerBuilder.build());
} catch (SchedulerException e) {
log.error(e.getMessage());
} catch (RuntimeException e) {
log.error(e.getMessage());
} catch (Exception e) {
log.error(e.getMessage());
}
}
/**
* 删除定时任务
*
* @param className
*/
@Override
public void schedulerDelete(String className) {
try {
scheduler.pauseTrigger(TriggerKey.triggerKey(className));
scheduler.unscheduleJob(TriggerKey.triggerKey(className));
scheduler.deleteJob(JobKey.jobKey(className));
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
3、编写 Job 执行类
package com.cxy.job.task;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class JobTest implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
String jobName = context.getJobDetail().getKey().toString().substring(8);
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String param = jobDataMap.getString("param");
log.info("执行 JobTest : {} - {}", jobName, param);
}
}
4、编写 Init 初始化类
package com.erayton.taxi.timer;
import java.text.SimpleDateFormat;
import org.quartz.JobDataMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import com.erayton.taxi.job.SysQuartzService;
import com.erayton.taxi.timer.job.JobTest;
@Component
@Order(0)
@Async
public class JobInit implements ApplicationRunner{
@Autowired
private SysQuartzService sysQuartzService;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void run(ApplicationArguments args) throws Exception {
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("param", "我的参数");
/**
* 1、秒针 0、10、20、30、40、50 秒时触发执行
* 2、任务不停止
*/
sysQuartzService.schedulerAdd("Test10s-1", JobTest.class, "0/10 * * * * ?", jobDataMap);
/**
* 1、秒针 0、10、20、30、40、50 秒时触发执行
* 2、任务结束于 2022-03-28 17:50:00
*/
sysQuartzService.schedulerAdd("Test10s-2", JobTest.class, "0/10 * * * * ?", null, sdf.parse("2022-03-28 17:50:00"), jobDataMap);
/**
* 1、秒针 0、10、20、30、40、50 秒时触发执行
* 2、任务开始于 2022-03-28 17:10:00
* 3、任务结束于 2022-03-28 17:50:00
*/
sysQuartzService.schedulerAdd("Test10s-3", JobTest.class, "0/10 * * * * ?", sdf.parse("2022-03-28 17:10:00"), sdf.parse("2022-03-28 17:50:00"), jobDataMap);
/**
* 1、每 10 秒钟触发执行
* 2、任务不停止
*/
sysQuartzService.schedulerAdd("Test10s-4", JobTest.class, -1, 10, jobDataMap);
/**
* 1、每 10 秒钟触发执行
* 2、任务结束于 2022-03-28 17:50:00
*/
sysQuartzService.schedulerAdd("Test10s-5", JobTest.class, -1, 10, null, sdf.parse("2022-03-28 17:50:00"), jobDataMap);
/**
* 1、每 10 秒钟触发执行
* 2、任务开始于 2022-03-28 17:10:00
* 3、任务结束于 2022-03-28 17:50:00
*/
sysQuartzService.schedulerAdd("Test10s-6", JobTest.class, -1, 10, sdf.parse("2022-03-28 17:10:00"), sdf.parse("2022-03-28 17:50:00"), jobDataMap);
/**
* 1、每 10 秒钟触发执行
* 2、执行 5 次后任务结束 (索引从 0 开始计算)
*/
sysQuartzService.schedulerAdd("Test10s-7", JobTest.class, 4, 10, jobDataMap);
}
}
四、总结
1、可根据自己的业务情况定制数据库存储【定时任务】
2、通过类名获取 Class
// 例如 className = com.cxy.job.task.JobTest
private static Job getClass(String className) throws Exception {
Class<?> class1 = Class.forName(className);
return (Job) class1.newInstance();
}
3、类名正则表达式
/^[a-zA-Z]+(\.([a-zA-Z])+)+$/
4、cron 可以使用 Quartz 自带验证方法
org.quartz.CronExpression.isValidExpression(cron);
- 打赏
请选择打赏方式
- 微信
- 支付宝