添加依赖
<!-- Quartz定时任务 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
添加配置
#quartz定时任务,采用数据库方式
spring:
quartz:
job-store-type: jdbc #数据持久化方式,可选值:MEMORY、JDBC
initialize-schema: embedded
#设置自动启动,默认为 true
auto-startup: false
#启动时更新己存在的Job
overwrite-existing-jobs: true
properties:
org:
quartz:
scheduler:
instanceName: MyScheduler
instanceId: AUTO
jobStore:
#如果不需要将调度命令(例如添加和删除triggers)绑定到其他事务,那么可以通过使用 JobStoreTX 管理事务
class: org.quartz.impl.jdbcjobstore.JobStoreTX
#设置数据库驱动代理,StdJDBCDelegate 是一个使用 JDBC 代码来执行其工作的代理. 其他代 理可以在"org.quartz.impl.jdbcjobstore“包或其子包中找到
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#通知 JobStore 使用的表前缀
tablePrefix: QRTZ_
#是否加入集群
isClustered: true
misfireThreshold: 60000
##容许的最大作业延长时间
clusterCheckinInterval: 10000
threadPool:
#quartz 使用的线程池类型,org.quartz.spi.ThreadPool
class: org.quartz.simpl.SimpleThreadPool
#线程池中的线程总个数,表示最多可以同时执行的个任务/作业个数
threadCount: 10
#线程优先级
threadPriority: 5
#线程继承初始化线程的上下文类加载器
threadsInheritContextClassLoaderOfInitializingThread: true
表结构
具体代码
------------------------controller开始----------------------------
1. 添加
/**
* 添加定时任务
*
* @param quartzJob
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public Result<?> add(@RequestBody QuartzJob quartzJob) {
String jobClassName = quartzJob.getJobClassName();
if(isContainChinese(jobClassName)){
return Result.error("JobClassName参数有误!");
}
quartzJobService.saveAndScheduleJob(quartzJob);
return Result.ok("创建定时任务成功");
}
2. 修改
/**
* 更新定时任务
*
* @param quartzJob
* @return
*/
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
public Result<?> eidt(@RequestBody QuartzJob quartzJob) {
try {
String jobClassName = quartzJob.getJobClassName();
if(isContainChinese(jobClassName)){
return Result.error("JobClassName参数有误!");
}
quartzJobService.editAndScheduleJob(quartzJob);
} catch (SchedulerException e) {
log.error(e.getMessage(),e);
return Result.error("更新定时任务失败!");
}
return Result.ok("更新定时任务成功!");
}
3. 删除
/**
* 通过id删除
*
* @param id
* @return
*/
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
QuartzJob quartzJob = quartzJobService.getById(id);
if (quartzJob == null) {
return Result.error("未找到对应实体");
}
quartzJobService.deleteAndStopJob(quartzJob);
return Result.ok("删除成功!");
4. 暂停任务
/**
* 暂停定时任务
*
* @param id
* @return
*/
@GetMapping(value = "/pause")
@ApiOperation(value = "暂停定时任务")
public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
QuartzJob job = quartzJobService.getById(id);
if (job == null) {
return Result.error("定时任务不存在!");
}
quartzJobService.pause(job);
return Result.ok("暂停定时任务成功");
}
5. 恢复任务
/**
* 启动定时任务
*
* @param id
* @return
*/
@GetMapping(value = "/resume")
@ApiOperation(value = "恢复定时任务")
public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
QuartzJob job = quartzJobService.getById(id);
if (job == null) {
return Result.error("定时任务不存在!");
}
quartzJobService.resumeJob(job);
//scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
return Result.ok("恢复定时任务成功");
}
6. 立即执行
/**
* 立即执行
* @param id
* @return
*/
@GetMapping("/execute")
public Result<?> execute(@RequestParam(name = "id", required = true) String id) {
QuartzJob quartzJob = quartzJobService.getById(id);
if (quartzJob == null) {
return Result.error("未找到对应实体");
}
try {
quartzJobService.execute(quartzJob);
} catch (Exception e) {
//e.printStackTrace();
log.info("定时任务 立即执行失败>>"+e.getMessage());
return Result.error("执行失败!");
}
return Result.ok("执行成功!");
}
---------------------controller结束---------------------------------
-------------------------service开始----------------------------------------
7. 保存
/**
* 保存&启动定时任务
*/
@Override
public boolean saveAndScheduleJob(QuartzJob quartzJob) {
// DB设置修改
quartzJob.setDelFlag(CommonConstant.DEL_FLAG_0);
boolean success = this.save(quartzJob);
if (success) {
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
// 定时器添加
this.schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
}
}
return success;
}
/**
* 添加定时任务
*
* @param jobClassName
* @param cronExpression
* @param parameter
*/
private void schedulerAdd(String id, String jobClassName, String cronExpression, String parameter) {
try {
// 启动调度器
scheduler.start();
// 构建job信息
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(id).usingJobData("parameter", parameter).build();
// 表达式调度构建器(即任务执行的时间)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
throw new JeecgBootException("创建定时任务失败", e);
} catch (RuntimeException e) {
throw new JeecgBootException(e.getMessage(), e);
}catch (Exception e) {
throw new JeecgBootException("后台找不到该类名:" + jobClassName, e);
}
}
8. 编辑
/**
* 编辑&启停定时任务
* @throws SchedulerException
*/
@Override
public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
schedulerDelete(quartzJob.getId());
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
}else{
//暂停任务
scheduler.pauseJob(JobKey.jobKey(quartzJob.getId()));
}
return this.updateById(quartzJob);
}
9. 删除定时任务
/**
* 删除定时任务
*
* @param id
*/
private void schedulerDelete(String id) {
try {
scheduler.pauseTrigger(TriggerKey.triggerKey(id));// 停止触发器
scheduler.unscheduleJob(TriggerKey.triggerKey(id));// 移除触发器
scheduler.deleteJob(JobKey.jobKey(id));// 删除任务
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new JeecgBootException("删除定时任务失败");
}
}
10. 暂停定时任务
/**
* 暂停定时任务
* @param quartzJob
*/
@Override
public void pause(QuartzJob quartzJob){
schedulerDelete(quartzJob.getId());
quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
this.updateById(quartzJob);
}
11. 恢复定时任务
/**
* 恢复定时任务
*/
@Override
public boolean resumeJob(QuartzJob quartzJob) {
schedulerDelete(quartzJob.getId());
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
return this.updateById(quartzJob);
}
12. 立即执行
/**
* 执行定时任务
* @param quartzJob
* @throws Exception
*/
@Override
public void execute(QuartzJob quartzJob) throws Exception {
String jobName = quartzJob.getJobClassName().trim();
Date startDate = new Date();
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
String identity = jobName + ymd;
//0.1秒后执行 只执行一次
startDate.setTime(startDate.getTime() + 100L);
// 定义一个Trigger
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
.withIdentity(identity, JOB_TEST_GROUP)
.startAt(startDate)
.build();
// 构建job信息
JobDetail jobDetail = JobBuilder.newJob(getClass(jobName).getClass()).withIdentity(identity).usingJobData("parameter", quartzJob.getParameter()).build();
// 将trigger和 jobDetail 加入这个调度
scheduler.scheduleJob(jobDetail, trigger);
// 启动scheduler
scheduler.start();
}
-----------------------------service结束------------------------------------
执行的任务内容
/**
* 定时任务内容
*
*/
@Slf4j
public class BridgeDeviceJob implements Job {
/**
* 当前任务内容
* @param jobExecutionContext
* @throws JobExecutionException
*/
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info(String.format(" 数据接收定时任务 ! 时间:" + DateUtils.getTimestamp()));
//具体任务内容
}
}
注意:1.实现org.quartz.Job接口,重新execute()方法.方法中写任务具体内容.
补充点
CronTrigger
withMisfireHandlingInstructionDoNothing
——不触发立即执行
——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行
withMisfireHandlingInstructionIgnoreMisfires
——以错过的第一个频率时间立刻开始执行
——重做错过的所有频率周期后
——当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行
withMisfireHandlingInstructionFireAndProceed
——以当前时间为触发频率立刻触发一次执行
——然后按照Cron频率依次执行