quartz依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
建表sql:
CREATE TABLE `schedule_job` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_name` varchar(255) DEFAULT NULL,
`cron_expression` varchar(255) DEFAULT NULL,
`bean_name` varchar(255) DEFAULT NULL,
`method_name` varchar(255) DEFAULT NULL,
`status` int(1) NOT NULL DEFAULT '1' COMMENT '状态 1.启动 2.暂停',
`delete_flag` int(1) NOT NULL DEFAULT '0' COMMENT '是否删除 0.否 1.是',
`creator_id` int(11) DEFAULT NULL COMMENT '创建人id',
`creator_name` varchar(45) DEFAULT NULL COMMENT '创建人',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间',
`equipment_control_id` bigint(20) DEFAULT NULL,
`pattern_control_id` bigint(20) DEFAULT NULL,
`join_control_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
定义实体类:
package com.ljp.quartz.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 定时任务实体类
*
* @Author: ljp
* @CreateDate: 2021/3/23 18:12
*/
@Data
public class ScheduleJob implements Serializable {
private static final long serialVersionUID = 2190790930184845880L;
/**
* 主键
*/
@TableId("id")
private Integer id;
/**
* 任务名称
*/
private String jobName;
/**
* cron表达式
*/
private String cronExpression;
/**
* 设备一键控制id
*/
private Long equipmentControlId;
/**
* 亮化模式控制id
*/
private Long patternControlId;
/**
* 联控id
*/
private Long joinControlId;
/**
* 服务名称
*/
private String beanName;
/**
* 方法名称
*/
private String methodName;
/**
* 状态 1.启动 2.暂停
*/
private int status;
/**
* 是否删除 0.否 1.是
*/
private int deleteFlag;
/**
* 创建人id
*/
private Integer creatorId;
/**
* 创建人
*/
private String creatorName;
/**
* 创建时间
*/
private LocalDateTime createdTime;
/**
* 更新时间
*/
private LocalDateTime updatedTime;
}
定义枚举类
/**
* 启动状态枚举类
*
* @author ljp
* @CreateDate: 2021/3/23 18:12
*/
public enum JobOperateEnum {
START(1, "启动"),
PAUSE(2, "暂停"),
DELETE(3, "删除");
/**
* value
*/
private final Integer value;
/**
* desc
*/
private final String desc;
JobOperateEnum(final Integer value, final String desc) {
this.value = value;
this.desc = desc;
}
public Serializable getValue() {
return this.value;
}
/**
* Jackson 注解为 JsonValue 返回中文 json 描述
*
* @return
*/
public String getDesc() {
return this.desc;
}
public String getEnumName() {
return name();
}
}
quartz配置类:
package com.ljp.quartz.config;
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
/**
* QuartzConfig
*
* @Author: ljp
* @CreateDate: 2021/3/23 18:28
*/
@Configuration
public class QuartzConfig {
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
//覆盖已存在的任务
schedulerFactoryBean.setOverwriteExistingJobs(true);
//延时20秒启动定时任务,避免系统未完全启动却开始执行定时任务的情况
// schedulerFactoryBean.setStartupDelay(20);
return schedulerFactoryBean;
}
/**
* 创建schedule
*
* @return
*/
@Bean(name = "scheduler")
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}
quartz工厂配置类:
package com.ljp.quartz.scheduler;
import com.ljp.quartz.entity.ScheduleJob;
import com.ljp.quartz.scheduler.job.MainJob;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import java.lang.reflect.Method;
/**
* quartz工厂
*
* @Author: ljp
* @CreateDate: 2021/3/24 10:08
*/
public class QuartzFactory implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) {
//获取调度数据
ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
try {
//利用反射执行对应方法
Method method = MainJob.class.getMethod("execute", scheduleJob.getClass());
method.setAccessible(true);
method.invoke(MainJob.class.newInstance(), scheduleJob);
} catch (Exception e) {
e.printStackTrace();
}
}
}
任务调度器:
package com.ljp.quartz.scheduler;
import com.ljp.quartz.service.QuartzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* JobSchedule
* @Author: ljp
* @CreateDate: 2021/3/24 13:30
*/
@Component
public class JobSchedule implements CommandLineRunner {
@Autowired
private QuartzService taskService;
/**
* 任务调度开始
*
* @param strings
* @throws Exception
*/
@Override
public void run(String... strings) throws Exception {
System.out.println("任务调度开始==============任务调度开始");
taskService.timingTask();
System.out.println("任务调度结束==============任务调度结束");
}
}
反射工具类:
package com.ljp.quartz.util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* 任务调度工具类
*
* @Author: ljp
* @CreateDate: 2021/3/24 10:08
*/
@Component
public class SpringUtil implements BeanFactoryPostProcessor {
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringUtil.beanFactory = beanFactory;
}
public static Object getBean(String name) {
return beanFactory.getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return beanFactory.getBean(clazz);
}
}
quartzService:
package com.ljp.quartz.service;
import com.ljp.quartz.entity.ScheduleJob;
import com.ljp.quartz.enums.JobOperateEnum;
import org.quartz.SchedulerException;
/**
* quartz service层
*
* @Author: ljp
* @CreateDate: 2021/3/24 10:04
*/
public interface QuartzService {
/**
* 服务器启动执行定时任务
*/
void timingTask() throws SchedulerException;
/**
* 新增定时任务
*
* @param job 任务
*/
void addJob(ScheduleJob job) throws SchedulerException;
/**
* 操作定时任务
*
* @param jobOperateEnum 操作枚举
* @param job 任务
* @throws SchedulerException
*/
void operateJob(JobOperateEnum jobOperateEnum, ScheduleJob job) throws SchedulerException;
/**
* 启动所有任务
*
* @throws SchedulerException
*/
void startAllJob() throws SchedulerException;
/**
* 暂停所有任务
*
* @throws SchedulerException
*/
void pauseAllJob() throws SchedulerException;
}
实现类:
package com.ljp.quartz.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ljp.quartz.entity.ScheduleJob;
import com.ljp.quartz.enums.JobOperateEnum;
import com.ljp.quartz.scheduler.QuartzFactory;
import com.ljp.quartz.service.QuartzService;
import com.ljp.quartz.service.ScheduleJobService;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* quartz实现类
*
* @Author: ljp
* @CreateDate: 2021/3/24 10:06
*/
@Service
public class QuartzServiceImpl implements QuartzService {
/**
* 调度器
*/
@Autowired
private Scheduler scheduler;
@Autowired
private ScheduleJobService scheduleJobService;
/**
* 服务器启动执行定时任务
*/
@Override
public void timingTask() throws SchedulerException {
//查询数据库是否存在需要定时的任务
List<ScheduleJob> scheduleJobs = scheduleJobService.list(new QueryWrapper<ScheduleJob>().eq("status", 1).eq("delete_flag", 0));
if (scheduleJobs != null) {
for (ScheduleJob scheduleJob : scheduleJobs) {
addJob(scheduleJob);
}
}
}
/**
* 新增定时任务
*
* @param job 任务
*/
@Override
public void addJob(ScheduleJob job) throws SchedulerException {
//创建触发器
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName())
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
.startNow()
.build();
//创建任务
JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class)
.withIdentity(job.getJobName())
.build();
//传入调度的数据,在QuartzFactory中需要使用
jobDetail.getJobDataMap().put("scheduleJob", job);
//调度作业
scheduler.scheduleJob(jobDetail, trigger);
}
/**
* 操作定时任务
*
* @param jobOperateEnum 操作枚举
* @param job 任务
* @throws SchedulerException
*/
@Override
public void operateJob(JobOperateEnum jobOperateEnum, ScheduleJob job) throws SchedulerException {
JobKey jobKey = new JobKey(job.getJobName());
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null) {
//抛异常
}
switch (jobOperateEnum) {
case START:
scheduler.resumeJob(jobKey);
break;
case PAUSE:
scheduler.pauseJob(jobKey);
break;
case DELETE:
scheduler.deleteJob(jobKey);
break;
}
}
@Override
public void startAllJob() throws SchedulerException {
scheduler.start();
}
@Override
public void pauseAllJob() throws SchedulerException {
scheduler.standby();
}
}
ScheduleJobService:
package com.ljp.quartz.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ljp.quartz.entity.ScheduleJob;
import org.quartz.SchedulerException;
/**
* 定时任务service
*
* @Author: ljp
* @CreateDate: 2021/3/24 9:51
*/
public interface ScheduleJobService extends IService<ScheduleJob> {
/**
* 新增定时任务
*
* @param job 任务
*/
void add(ScheduleJob job) throws SchedulerException;
/**
* 启动定时任务
*
* @param id 任务id
*/
void start(int id) throws SchedulerException;
/**
* 暂停定时任务
*
* @param id 任务id
*/
void pause(int id) throws SchedulerException;
/**
* 删除定时任务
*
* @param id 任务id
*/
void delete(int id) throws SchedulerException;
/**
* 启动所有定时任务
*/
void startAllJob() throws SchedulerException;
/**
* 暂停所有定时任务
*/
void pauseAllJob() throws SchedulerException;
}
ScheduleJob实现类:
package com.ljp.quartz.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljp.quartz.entity.ScheduleJob;
import com.ljp.quartz.enums.JobOperateEnum;
import com.ljp.quartz.mapper.ScheduleJobMapper;
import com.ljp.quartz.service.QuartzService;
import com.ljp.quartz.service.ScheduleJobService;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 定时任务实现类
*
* @Author: ljp
* @CreateDate: 2021/3/24 9:51
*/
@Service
public class ScheduleJobServiceImpl extends ServiceImpl<ScheduleJobMapper, ScheduleJob> implements ScheduleJobService {
@Autowired
private QuartzService quartzService;
/**
* 添加定时任务
*
* @param job 任务
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void add(ScheduleJob job) throws SchedulerException {
save(job);
//加入job
quartzService.addJob(job);
}
/**
* 开启定时任务
*
* @param id 任务id
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void start(int id) throws SchedulerException {
ScheduleJob job = this.getById(id);
job.setStatus(1);
updateById(job);
//执行job
quartzService.operateJob(JobOperateEnum.START, job);
}
/**
* 暂停定时任务
*
* @param id 任务id
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void pause(int id) throws SchedulerException {
ScheduleJob job = this.getById(id);
job.setStatus(2);
updateById(job);
//执行job
quartzService.operateJob(JobOperateEnum.PAUSE, job);
}
/**
* 删除定时任务
*
* @param id 任务id
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(int id) throws SchedulerException {
ScheduleJob job = this.getById(id);
job.setDeleteFlag(1);
updateById(job);
//执行job
quartzService.operateJob(JobOperateEnum.DELETE, job);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void startAllJob() throws SchedulerException {
ScheduleJob job = new ScheduleJob();
job.setStatus(1);
update(job, new QueryWrapper<>());
//执行job
quartzService.startAllJob();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void pauseAllJob() throws SchedulerException {
ScheduleJob job = new ScheduleJob();
job.setStatus(2);
update(job, new QueryWrapper<>());
//执行job
quartzService.pauseAllJob();
}
}
控制器类:
package com.ljp.quartz.controller;
import com.ljp.quartz.common.ResultUtil;
import com.ljp.quartz.entity.ScheduleJob;
import com.ljp.quartz.service.ScheduleJobService;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Random;
/**
* 定时任务控制器类
*
* @Author: ljp
* @CreateDate: 2021/3/24 10:27
*/
@RestController
@RequestMapping("/quartz")
public class SchedulerController {
@Autowired
private ScheduleJobService scheduleJobService;
public static void main(String[] args) {
Random random = new Random();
System.out.println(random.nextInt(59));
}
/**
* 查询所有定时任务
*
* @return
*/
@GetMapping("/list")
public Object list() {
return ResultUtil.success(scheduleJobService.list());
}
@PostMapping("/add")
public Object add() throws SchedulerException {
for (int i = 1; i <= 100; i++) {
ScheduleJob scheduleJob = new ScheduleJob();
scheduleJob.setJobName("测试任务" + i + "号");
scheduleJob.setCronExpression("0/" + new Random().nextInt(59) + " * * * * ?");
scheduleJob.setStatus(2);
scheduleJob.setDeleteFlag(0);
scheduleJobService.add(scheduleJob);
}
// scheduleJob.setDeleteFlag(0);
// scheduleJobService.add(scheduleJob);
return ResultUtil.success();
}
@GetMapping("/start/{id}")
public Object start(@PathVariable("id") Integer id) throws SchedulerException {
scheduleJobService.start(id);
return ResultUtil.success();
}
@GetMapping("/pause/{id}")
public Object pause(@PathVariable("id") Integer id) throws SchedulerException {
scheduleJobService.pause(id);
return ResultUtil.success();
}
@GetMapping("/delete/{id}")
public Object delete(@PathVariable("id") Integer id) throws SchedulerException {
scheduleJobService.delete(id);
return ResultUtil.success();
}
@GetMapping("/startAllJob")
public Object startAllJob() throws SchedulerException {
scheduleJobService.startAllJob();
return ResultUtil.success();
}
@GetMapping("/pauseAllJob")
public Object pauseAllJob() throws SchedulerException {
scheduleJobService.pauseAllJob();
return ResultUtil.success();
}
}
这里的添加方法我写了一个循环,用来测试的。
文章主要是借鉴https://www.jianshu.com/p/b9955ee663b5这位老哥的文章,做了一些调整