maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<exclusions>
<exclusion>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
</exclusions>
</dependency>
以上两种依赖没有本质区别,只是在使用在存在区别,第一种用于springboot项目集成,配置都基本springboot自动帮我们配置好了,只需要实现关键的一些类即可,第二种就需要我们自己配置,实现一些东西但相应会跟灵活些。这里我们选用第一种,这里需要的quartz数据库表结构可以参考的【quartz】:quartz api 详解这篇文章。
配置:
spring:
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#数据库方式
job-store-type: jdbc
#初始化表结构
#jdbc:
#initialize-schema: never
新建任务:
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* QuartzTestJob
*
* @author seer
* @date 2018/10/23 14:47
*/
@Slf4j
public class QuartzTestJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info("这里写定时任务业务逻辑。。。");
}
}
定时任务管理:
public class ScheduleJob {
/**
* 任务名称
*/
private String jobName;
/**
* 任务分组
*/
private String jobGroup;
/**
* 任务状态 是否启动任务
*/
private String jobStatus;
/**
* cron表达式
*/
private String cronExpression;
/**
* 描述
*/
private String description;
/**
* 任务执行时调用哪个类的方法 包名+类名
*/
private String beanClass;
/**
* 任务是否有状态
*/
private String isConcurrent;
/**
* Spring bean
*/
private String springBean;
/**
* 任务调用的方法名
*/
private String methodName;
/**
* 任务开始时间
*/
private Date startTime;
/**
* 任务结束时间
*/
private Date endTime;
// 省略了getter,setter
}
@Slf4j
@Component
public class QuartzManager {
@Autowired
@Qualifier("Scheduler")
private Scheduler scheduler;
/**
* 添加CronTrigger任务
*/
public void addJobByCronTrigger(ScheduleJob job) {
try {
// 创建jobDetail实例,绑定Job实现类
// 指明job的名称,所在组的名称,以及绑定job类
Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(job.getBeanClass()).newInstance().getClass());
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(job.getJobName(), job.getJobGroup()).build();
// 定义调度触发规则
// 使用cornTrigger规则 触发器key
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression())).startNow().build();
// 把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
// 启动
if (!scheduler.isShutdown()) {
scheduler.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 添加SimpleTrigger任务
*/
public void addJobBySimpleTrigger(ScheduleJob job) {
try {
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity(job.getJobName(), job.getJobGroup()).build();
// 每5秒执行一次,共执行四次(注意参数为3)
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5)
.withRepeatCount(3);
// 使用SimpleTrigger规则 触发器key
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
.startAt(job.getStartTime())
.endAt(job.getEndTime())
.withSchedule(scheduleBuilder)
.build();
// 创建scheduler(手动启动)
// Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
// 启动
if (!scheduler.isShutdown()) {
scheduler.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取所有计划中的任务列表
*/
public List<ScheduleJob> getAllJob() throws SchedulerException {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
ScheduleJob job = new ScheduleJob();
job.setJobName(jobKey.getName());
job.setJobGroup(jobKey.getGroup());
job.setDescription("触发器:" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
}
jobList.add(job);
}
}
return jobList;
}
/**
* 所有正在运行的job
*/
public List<ScheduleJob> getRunningJob() throws SchedulerException {
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
ScheduleJob job = new ScheduleJob();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
job.setJobName(jobKey.getName());
job.setJobGroup(jobKey.getGroup());
job.setDescription("触发器:" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
}
jobList.add(job);
}
return jobList;
}
/**
* 暂停一个job
*/
public void pauseJob(ScheduleJob scheduleJob) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.pauseJob(jobKey);
}
/**
* 恢复一个job
*/
public void resumeJob(ScheduleJob scheduleJob) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.resumeJob(jobKey);
}
/**
* 删除一个job
*/
public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.deleteJob(jobKey);
}
/**
* 触发执行job
*/
public void triggerJob(ScheduleJob scheduleJob) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.triggerJob(jobKey);
}
/**
* 更新job时间表达式
*/
public void updateJobCron(ScheduleJob scheduleJob) throws SchedulerException {
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
scheduler.rescheduleJob(triggerKey, trigger);
}
}
service:
package com.hzl.admin.api.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.hzl.admin.api.config.quartz.ScheduleJob;
import com.hzl.admin.api.service.IJobService;
import com.hzl.admin.api.config.quartz.QuartzManager;
import com.hzl.admin.api.config.quartz.ScheduleJobUtils;
import com.hzl.admin.api.entity.Task;
import com.hzl.admin.api.mapper.master.TaskMapper;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class JobServiceImpl extends ServiceImpl<TaskMapper, Task> implements IJobService {
@Autowired
private TaskMapper taskMapper;
@Autowired
private QuartzManager quartzManager;
@Override
public Task getTask(Long id) {
return taskMapper.selectById(id);
}
@Override
public List<Task> listTask(Task task) {
return taskMapper.selectList(new EntityWrapper<Task>(task));
}
@Override
public int remove(Long id) {
try {
Task scheduleJob = getTask(id);
quartzManager.deleteJob(ScheduleJobUtils.entityToData(scheduleJob));
return taskMapper.deleteById(id);
} catch (SchedulerException e) {
e.printStackTrace();
}
return 0;
}
@Override
public Boolean batchRemove(Long[] ids) {
for (Long id : ids) {
try {
Task scheduleJob = getTask(id);
quartzManager.deleteJob(ScheduleJobUtils.entityToData(scheduleJob));
taskMapper.deleteById(id);
} catch (SchedulerException e) {
e.printStackTrace();
return false;
}
}
return true;
}
@Override
public void initSchedule() throws SchedulerException {
// 这里获取任务信息数据
List<Task> jobList = taskMapper.selectList(new EntityWrapper<Task>());
for (Task scheduleJob : jobList) {
if ("1".equals(scheduleJob.getJobStatus())) {
ScheduleJob job = ScheduleJobUtils.entityToData(scheduleJob);
quartzManager.addJobByCronTrigger(job);
}
}
}
@Override
public Boolean updateCron(Long id) throws SchedulerException {
Task scheduleJob = getTask(id);
if (scheduleJob == null) {
return false;
}
if (ScheduleJob.STATUS_RUNNING.equals(scheduleJob.getJobStatus())) {
quartzManager.updateJobCron(ScheduleJobUtils.entityToData(scheduleJob));
}
int num = taskMapper.updateById(scheduleJob);
if (num <= 0) {
return false;
}
return true;
}
@Override
public Boolean startJob(Long taskId) {
Task scheduleJob = getTask(taskId);
quartzManager.addJobByCronTrigger(ScheduleJobUtils.entityToData(scheduleJob));
return true;
}
@Override
public Boolean stopJob(Long taskId){
Task scheduleJob = getTask(taskId);
try {
quartzManager.pauseJob(ScheduleJobUtils.entityToData(scheduleJob));
return true;
} catch (SchedulerException e) {
e.printStackTrace();
}
return false;
}
}
controller:
package com.hzl.admin.api.controller;
import com.hzl.admin.api.entity.Task;
import com.hzl.admin.api.service.IJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/common/job")
public class JobController extends BaseController {
@Autowired
private IJobService jobService;
@GetMapping("/list")
public List<Task> list() {
List<Task> list = jobService.listTask(null);
return list;
}
@GetMapping("/start/{id}")
public Boolean startJob(@PathVariable("id") Long taskId){
boolean flag = jobService.startJob(taskId);
return flag;
}
@GetMapping("/stop/{id}")
public Boolean triggerJob(@PathVariable("id") Long taskId){
boolean flag = jobService.stopJob(taskId);
return flag;
}
// @GetMapping("/edit/{id}")
// String edit(@PathVariable("id") Long id, Model model) {
// Task job = jobService.get(id);
// model.addAttribute("job", job);
// return "common/job/edit";
// }
/**
* 信息
*/
// @GetMapping("/info/{id}")
// public R info(@PathVariable("id") Long id) {
// Task taskScheduleJob = jobService.get(id);
// return R.ok().put("taskScheduleJob", taskScheduleJob);
// }
/**
* 保存
*/
// @PostMapping("/save")
// public R save(Task taskScheduleJob) {
// if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
// return R.error(1, "演示系统不允许修改,完整体验请部署程序");
// }
// if (jobService.save(taskScheduleJob) > 0) {
// return R.ok();
// }
// return R.error();
// }
/**
* 修改
*/
// @PostMapping("/update")
// public R update(Task taskScheduleJob) {
// if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
// return R.error(1, "演示系统不允许修改,完整体验请部署程序");
// }
// jobService.update(taskScheduleJob);
// return R.ok();
// }
/**
* 删除
*/
// @PostMapping("/remove")
// public R remove(Long id) {
// if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
// return R.error(1, "演示系统不允许修改,完整体验请部署程序");
// }
// if (jobService.remove(id) > 0) {
// return R.ok();
// }
// return R.error();
// }
/**
* 删除
*/
// @PostMapping("/batchRemove")
// public R remove(@RequestParam("ids[]") Long[] ids) {
// if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
// return R.error(1, "演示系统不允许修改,完整体验请部署程序");
// }
// jobService.batchRemove(ids);
//
// return R.ok();
// }
// @PostMapping(value = "/changeJobStatus")
// public R changeJobStatus(Long id, String cmd) {
// if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
// return R.error(1, "演示系统不允许修改,完整体验请部署程序");
// }
// String label = "停止";
// if ("start".equals(cmd)) {
// label = "启动";
// } else {
// label = "停止";
// }
// try {
// jobService.changeStatus(id, cmd);
// return R.ok("任务" + label + "成功");
// } catch (Exception e) {
// e.printStackTrace();
// }
// return R.ok("任务" + label + "失败");
// }
}