背景: 项目中很多时候会有一些定时任务,而这些定时任务在特殊时期还有可能改变运行周期,这时候框架quartz就很好的解决了这个问题
项目结构图
Springboot直接支持该依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
数据库中表SQL
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for sys_job_quartz -- ---------------------------- DROP TABLE IF EXISTS `sys_job_quartz`; CREATE TABLE `sys_job_quartz` ( `id` int(20) NOT NULL AUTO_INCREMENT, `job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务名', `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务描述', `cron_expression` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'cron表达式', `expression_desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '表达式描述', `bean_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名', `job_status` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '1' COMMENT '任务状态 0:停止 1:运行 2:暂停 -1:删除', `job_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'report' COMMENT '任务分组', `creator` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', `modifier` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更新者', `modify_time` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', PRIMARY KEY (`id`) USING BTREE ) ENGINE = MyISAM AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
下面是具体的代码
quartz配置类,config/quartz.properties配置文件可以在Resources中添加,可增加各种配置,这里暂且不使用
package com.milla.study.netbase.expert.quartz.config;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import java.io.IOException;
import java.util.Properties;
/**
* @Package: com.milla.study.netbase.expert.quartz.config
* @Description: <动态任务配置类>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:36
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:36
* @UpdateRemark: <>
* @Version: 1.0
*/
@Configuration
public class QuartzConfig {
@Bean
public SchedulerFactoryBean schedulerFactoryBean(@Qualifier("quartz") Properties properties) {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
try {
schedulerFactoryBean.setOverwriteExistingJobs(true);
schedulerFactoryBean.setQuartzProperties(properties);
schedulerFactoryBean.setJobFactory(new SpringBeanJobFactory());
} catch (Exception e) {
e.printStackTrace();
}
return schedulerFactoryBean;
}
// 指定quartz.properties,可在配置文件中配置相关属性
@Bean("quartz")
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
// propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
// 创建schedule
@Bean(name = "scheduler")
public Scheduler scheduler(SchedulerFactoryBean scheduler) {
return scheduler.getScheduler();
}
}
任务实体类
package com.milla.study.netbase.expert.quartz.dto;
import lombok.Data;
import java.util.Date;
/**
* @Package: com.milla.study.netbase.expert.quartz.dto
* @Description: <任务实体>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:40
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:40
* @UpdateRemark: <>
* @Version: 1.0
*/
@Data
public class QuartzJobDTO {
/**
* 主键
*/
private Integer id;
/**
* 任务名
*/
private String jobName;
/**
* 任务描述
*/
private String description;
/**
* cron表达式
*/
private String cronExpression;
/**
* 表达式描述
*/
private String expressionDesc;
/**
* 任务执行时调用哪个类的方法 包名+类名
*/
private String beanClass;
/**
* 任务状态
*/
private String jobStatus;
/**
* 任务分组
*/
private String jobGroup;
/**
* 创建者
*/
private String creator;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新者
*/
private String modifier;
/**
* 更新时间
*/
private Date modifyTime;
}
任务操作类[包含启动任务,暂停任务,重启任务,修改任务等等]
package com.milla.study.netbase.expert.quartz.util;
import com.milla.study.netbase.expert.quartz.dto.QuartzJobDTO;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @Package: com.milla.study.netbase.expert.quartz.util
* @Description: <计划任务管理>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:52
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:52
* @UpdateRemark: <>
* @Version: 1.0
*/
@Component
public class QuartzManager {
@Autowired
private Scheduler scheduler;
/**
* 增加一个任务
*
* @param job 任务
* @throws SchedulerException 调度异常
* @throws ClassNotFoundException 类找不到
*/
public void addJob(QuartzJobDTO job) throws SchedulerException, ClassNotFoundException {
//加载指定任务的实例class文件
Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(job.getBeanClass()));
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(job.getJobName(), job.getJobGroup()).build();
// 定义调度触发规则
// 使用cornTrigger规则
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())// 触发器key
.startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression())).startNow().build();
// 把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
// 启动
if (!scheduler.isShutdown()) {
scheduler.start();
}
}
/**
* 获取所有计划中的任务列表
*
* @return
* @throws SchedulerException
*/
public List<QuartzJobDTO> listJob() throws SchedulerException {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
List<QuartzJobDTO> jobList = new ArrayList<>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
QuartzJobDTO job = new QuartzJobDTO();
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
*
* @return
* @throws SchedulerException
*/
public List<QuartzJobDTO> listRunningJob() throws SchedulerException {
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
List<QuartzJobDTO> jobList = new ArrayList<QuartzJobDTO>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
QuartzJobDTO job = new QuartzJobDTO();
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
*
* @param job
* @throws SchedulerException
*/
public void pauseJob(QuartzJobDTO job) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
scheduler.pauseJob(jobKey);
}
/**
* 恢复一个job
*
* @param job
* @throws SchedulerException
*/
public void resumeJob(QuartzJobDTO job) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
scheduler.resumeJob(jobKey);
}
/**
* 删除一个job
*
* @param job
* @throws SchedulerException
*/
public void deleteJob(QuartzJobDTO job) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
scheduler.deleteJob(jobKey);
}
/**
* 立即执行job
*
* @param job
* @throws SchedulerException
*/
public void runJobNow(QuartzJobDTO job) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
scheduler.triggerJob(jobKey);
}
/**
* 更新job时间表达式
*
* @param job
* @throws SchedulerException
*/
public void updateJobCron(QuartzJobDTO job) throws SchedulerException {
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
scheduler.rescheduleJob(triggerKey, trigger);
}
}
Mapper文件
package com.milla.study.netbase.expert.quartz.mapper;
import com.milla.study.netbase.expert.quartz.dto.QuartzJobDTO;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface QuartzJobDTOMapper {
int deleteByPrimaryKey(Integer id);
int insert(QuartzJobDTO record);
int insertSelective(QuartzJobDTO record);
QuartzJobDTO selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(QuartzJobDTO record);
int updateByPrimaryKey(QuartzJobDTO record);
List<QuartzJobDTO> selectJob();
List<QuartzJobDTO> selectJobByGroup(@Param("report") String report);
QuartzJobDTO selectByJobName(QuartzJobDTO job);
}
与之对应的xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.milla.study.netbase.expert.quartz.mapper.QuartzJobDTOMapper">
<resultMap id="BaseResultMap" type="com.milla.study.netbase.expert.quartz.dto.QuartzJobDTO">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="job_name" property="jobName" jdbcType="VARCHAR"/>
<result column="description" property="description" jdbcType="VARCHAR"/>
<result column="cron_expression" property="cronExpression" jdbcType="VARCHAR"/>
<result column="expression_desc" property="expressionDesc" jdbcType="VARCHAR"/>
<result column="bean_class" property="beanClass" jdbcType="VARCHAR"/>
<result column="job_status" property="jobStatus" jdbcType="VARCHAR"/>
<result column="job_group" property="jobGroup" jdbcType="VARCHAR"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="modifier" property="modifier" jdbcType="VARCHAR"/>
<result column="modify_time" property="modifyTime" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id, job_name, description, cron_expression, expression_desc, bean_class, job_status, job_group, creator,
create_time, modifier, modify_time
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
select
<include refid="Base_Column_List"/>
from sys_job_quartz
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from sys_job_quartz
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.aimsphm.nuclear.common.quartz.dto.QuartzJobDTO">
<selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
insert into sys_job_quartz (job_name, description, cron_expression,expression_desc,
bean_class, job_status, job_group,
creator, create_time, modifier,
modify_time)
values (#{jobName,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
#{cronExpression,jdbcType=VARCHAR},#{expressionDesc,jdbcType=VARCHAR}
#{beanClass,jdbcType=VARCHAR}, #{jobStatus,jdbcType=VARCHAR}, #{jobGroup,jdbcType=VARCHAR},
#{creator,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, #{modifier,jdbcType=VARCHAR},
#{modifyTime,jdbcType=TIMESTAMP})
</insert>
<insert id="insertSelective" parameterType="com.aimsphm.nuclear.common.quartz.dto.QuartzJobDTO">
<selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
insert into sys_job_quartz
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="jobName != null">
job_name,
</if>
<if test="description != null">
description,
</if>
<if test="cronExpression != null">
cron_expression,
</if>
<if test="expressionDesc!= null">
expression_desc,
</if>
<if test="beanClass != null">
bean_class,
</if>
<if test="jobStatus != null">
job_status,
</if>
<if test="jobGroup != null">
job_group,
</if>
<if test="creator != null">
creator,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="modifier != null">
modifier,
</if>
<if test="modifyTime != null">
modify_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="jobName != null">
#{jobName,jdbcType=VARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=VARCHAR},
</if>
<if test="cronExpression != null">
#{cronExpression,jdbcType=VARCHAR},
</if>
<if test="expressionDesc != null">
#{expressionDesc,jdbcType=VARCHAR},
</if>
<if test="beanClass != null">
#{beanClass,jdbcType=VARCHAR},
</if>
<if test="jobStatus != null">
#{jobStatus,jdbcType=VARCHAR},
</if>
<if test="jobGroup != null">
#{jobGroup,jdbcType=VARCHAR},
</if>
<if test="creator != null">
#{creator,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="modifier != null">
#{modifier,jdbcType=VARCHAR},
</if>
<if test="modifyTime != null">
#{modifyTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.aimsphm.nuclear.common.quartz.dto.QuartzJobDTO">
update sys_job_quartz
<set>
<if test="jobName != null">
job_name = #{jobName,jdbcType=VARCHAR},
</if>
<if test="description != null">
description = #{description,jdbcType=VARCHAR},
</if>
<if test="cronExpression != null">
cron_expression = #{cronExpression,jdbcType=VARCHAR},
</if>
<if test="expressionDesc != null">
expression_desc = #{expressionDesc,jdbcType=VARCHAR},
</if>
<if test="beanClass != null">
bean_class = #{beanClass,jdbcType=VARCHAR},
</if>
<if test="jobStatus != null">
job_status = #{jobStatus,jdbcType=VARCHAR},
</if>
<if test="jobGroup != null">
job_group = #{jobGroup,jdbcType=VARCHAR},
</if>
<if test="creator != null">
creator = #{creator,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="modifier != null">
modifier = #{modifier,jdbcType=VARCHAR},
</if>
<if test="modifyTime != null">
modify_time = #{modifyTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.aimsphm.nuclear.common.quartz.dto.QuartzJobDTO">
update sys_job_quartz
set job_name = #{jobName,jdbcType=VARCHAR},
description = #{description,jdbcType=VARCHAR},
cron_expression = #{cronExpression,jdbcType=VARCHAR},
expression_desc = #{expressionDesc,jdbcType=VARCHAR},
bean_class = #{beanClass,jdbcType=VARCHAR},
job_status = #{jobStatus,jdbcType=VARCHAR},
job_group = #{jobGroup,jdbcType=VARCHAR},
creator = #{creator,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=TIMESTAMP},
modifier = #{modifier,jdbcType=VARCHAR},
modify_time = #{modifyTime,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectJob" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from sys_job_quartz
where job_status =1
</select>
<select id="selectJobByGroup" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from sys_job_quartz
where job_status =1 and job_group='report'
</select>
<select id="selectByJobName" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from sys_job_quartz
where job_name=#{jobName} and job_group= #{jobGroup}
</select>
</mapper>
任务状态枚举类
package com.milla.study.netbase.expert.quartz.enums;
/**
* @Package: com.milla.study.netbase.expert.quartz.enums
* @Description: <>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:58
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:58
* @UpdateRemark: <>
* @Version: 1.0
*/
public enum QuartzJobStateEnum {
STOPPED("0", "停止"),
RUNNING("1", "运行"),
DELETED("-1", "删除");
private String value;
private String code;
private QuartzJobStateEnum(String code, String value) {
this.value = value;
this.code = code;
}
public static QuartzJobStateEnum instance(String code) {
for (QuartzJobStateEnum e : QuartzJobStateEnum.values()) {
if (e.getCode().equals(code)) {
return e;
}
}
return null;
}
/**
* 获取value
*/
public String getValue() {
return value;
}
/**
* 获取code
*/
public String getCode() {
return code;
}
}
任务操作枚举类
package com.milla.study.netbase.expert.quartz.enums;
/**
* @Package: com.milla.study.netbase.expert.quartz.enums
* @Description: <对job进行的操作>
* @Author: MILLA
* @CreateDate: 2020/5/13 13:43
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/13 13:43
* @UpdateRemark: <>
* @Version: 1.0
*/
public enum QuartzJobOperateEnum {
stop, resume, update
}
任务操作业务接口
package com.milla.study.netbase.expert.quartz.service;
import com.milla.study.netbase.expert.quartz.dto.QuartzJobDTO;
import com.milla.study.netbase.expert.quartz.enums.QuartzJobOperateEnum;
import org.quartz.SchedulerException;
/**
* @Package: com.milla.study.netbase.expert.quartz.service
* @Description: <>
* @Author: MILLA
* @CreateDate: 2020/5/13 13:34
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/13 13:34
* @UpdateRemark: <>
* @Version: 1.0
*/
public interface QuartzManagerService {
void addJob(QuartzJobDTO job) throws ClassNotFoundException, SchedulerException;
void modifyJob(Integer id, QuartzJobOperateEnum operateEnum, QuartzJobDTO job) throws SchedulerException;
void removeJob(Integer id) throws SchedulerException;
}
任务操作实现类
package com.milla.study.netbase.expert.quartz.service.impl;
import com.milla.study.netbase.expert.quartz.dto.QuartzJobDTO;
import com.milla.study.netbase.expert.quartz.enums.QuartzJobOperateEnum;
import com.milla.study.netbase.expert.quartz.enums.QuartzJobStateEnum;
import com.milla.study.netbase.expert.quartz.mapper.QuartzJobDTOMapper;
import com.milla.study.netbase.expert.quartz.service.QuartzManagerService;
import com.milla.study.netbase.expert.quartz.util.QuartzManager;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* @Package: com.milla.study.netbase.expert.quartz.service.impl
* @Description: <任务管理业务类>
* @Author: MILLA
* @CreateDate: 2020/5/13 13:34
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/13 13:34
* @UpdateRemark: <>
* @Version: 1.0
*/
@Service
//在微服务中,该类按需启用使用下面的注解,该类能完成自动注入和不注入
@ConditionalOnProperty(prefix = "mybatis-plus", name = "quarzt-enable", havingValue = "1")
public class QuartzManagerServiceImpl implements QuartzManagerService {
@Autowired
private QuartzManager manager;
@Autowired(required = false)
private QuartzJobDTOMapper mapper;
@Override
@Transactional
public void addJob(QuartzJobDTO job) throws ClassNotFoundException, SchedulerException {
Assert.hasText(job.getJobName(), "任务名称不能为空");
Assert.hasText(job.getCronExpression(), "任务执行周期不能为空");
Assert.hasText(job.getJobGroup(), "任务分组不能为空");
QuartzJobDTO find = mapper.selectByJobName(job);
Assert.isNull(find, "要添加的任务已经存在");
mapper.insertSelective(job);
manager.addJob(job);
}
@Override
public void modifyJob(Integer id, QuartzJobOperateEnum operateEnum, QuartzJobDTO job) throws SchedulerException {
QuartzJobDTO find = mapper.selectByPrimaryKey(id);
Assert.notNull(find, "要操作的任务不存在");
if (StringUtils.hasText(job.getJobName())) {
find.setJobName(job.getJobName());
}
if (StringUtils.hasText(job.getJobGroup())) {
find.setJobGroup(job.getJobGroup());
}
if (StringUtils.hasText(job.getBeanClass())) {
find.setBeanClass(job.getBeanClass());
}
if (StringUtils.hasText(job.getModifier())) {
find.setModifier(job.getModifier());
}
switch (operateEnum) {
//删除
case stop:
find.setJobStatus(QuartzJobStateEnum.STOPPED.getCode());
manager.pauseJob(find);
break;
case resume:
find.setJobStatus(QuartzJobStateEnum.RUNNING.getCode());
manager.resumeJob(find);
break;
case update:
if (StringUtils.isEmpty(job.getCronExpression())) {
throw new RuntimeException("任务表达式书写错误");
}
find.setCronExpression(job.getCronExpression());
manager.updateJobCron(find);
break;
default:
throw new RuntimeException("任务不支持该操作");
}
mapper.updateByPrimaryKeySelective(find);
}
@Override
public void removeJob(Integer id) throws SchedulerException {
QuartzJobDTO find = mapper.selectByPrimaryKey(id);
Assert.notNull(find, "要操作的任务不存在");
find.setJobStatus("-1");
mapper.updateByPrimaryKeySelective(find);
manager.deleteJob(find);
}
}
controller层控制类
package com.milla.study.netbase.expert.quartz.controller;
import com.milla.study.netbase.expert.quartz.dto.QuartzJobDTO;
import com.milla.study.netbase.expert.quartz.enums.QuartzJobOperateEnum;
import com.milla.study.netbase.expert.quartz.service.QuartzManagerService;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
/**
* @Package: com.milla.study.netbase.expert.quartz.controller
* @Description: <>
* @Author: MILLA
* @CreateDate: 2020/5/13 13:23
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/13 13:23
* @UpdateRemark: <>
* @Version: 1.0
*/
@RestController
//@Api(tags = "任务管理")
@RequestMapping(value = "quartz", produces = MediaType.APPLICATION_JSON_VALUE)
public class QuartzJobController {
@Autowired(required = false)
private QuartzManagerService service;
@PostMapping
//@ApiOperation(value = "新增任务")
public void addJob(@RequestBody QuartzJobDTO job) throws ClassNotFoundException, SchedulerException {
checkService();
service.addJob(job);
}
private void checkService() {
if (service == null) {
throw new RuntimeException("当前服务没有开启任务管理模式");
}
}
@PutMapping("{id}")
//@ApiOperation(value = "修改任务", notes = "operateEnum值:stop, resume, update")
public void modifyJob(@PathVariable Integer id, @RequestBody QuartzJobDTO job, QuartzJobOperateEnum operateEnum) throws SchedulerException {
checkService();
service.modifyJob(id, operateEnum, job);
}
@DeleteMapping("{id}")
//@ApiOperation(value = "删除任务")
public void removeJob(@PathVariable Integer id) throws SchedulerException {
checkService();
service.removeJob(id);
}
}
至此,还需要一个真正被执行的job
package com.milla.study.netbase.expert.quartz.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* @Package: com.milla.study.netbase.expert.quartz.job
* @Description: <定时任务>
* @Author: MILLA
* @CreateDate: 2020/5/12 18:58
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 18:58
* @UpdateRemark: <>
* @Version: 1.0
*/
public class ExampleJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//此处是需要定时执行的业务
System.out.println("就做个打印吧");
}
}
此时可以写单元测试,或者是在controller中增加一个新方法模拟下
@GetMapping("test")
@ApiOperation(value = "测试增加任务")
public void test(ReportQueryBO query) throws SchedulerException, ClassNotFoundException {
QuartzJobDTO job = new QuartzJobDTO();
job.setBeanClass(PumpReportJob.class.getName());
job.setCronExpression("0/10 * * * * ?");
job.setJobName("test");
job.setJobGroup(UUIDUtils.randomUUID());
job.setDescription("修改描述");
job.setCreateTime(new Date());
job.setCreator("Milla");
job.setModifier("Milla's");
managerService.addJob(job);
}
这样这套完整的流程就基本上可以了。但是,一般情况都是将任务在数据库中配置好,在启动的时候加载所有需要指定的任务,所以需要一个初始化任务的类
package com.milla.study.netbase.expert.quartz.service;
import org.quartz.SchedulerException;
/**
* @Package: com.milla.study.netbase.expert.quartz.service
* @Description: <初始化任务>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:38
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:38
* @UpdateRemark: <>
* @Version: 1.0
*/
public interface QuartzJobService {
void initSchedule() throws SchedulerException, ClassNotFoundException;
}
默认实现类
package com.milla.study.netbase.expert.quartz.service.impl;
import com.milla.study.netbase.expert.quartz.service.QuartzJobService;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;
/**
* @Package: com.milla.study.netbase.expert.quartz.service.impl
* @Description: <为了防止注入异常增加一个默认实现>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:39
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:39
* @UpdateRemark: <>
* @Version: 1.0
*/
@Service("default")
public class QuartzJobServiceImpl implements QuartzJobService {
@Override
public void initSchedule() throws SchedulerException, ClassNotFoundException {
}
}
需要增加一个入口执行该初始化类
package com.milla.study.netbase.expert.quartz.listener;
import com.milla.study.netbase.expert.quartz.service.QuartzJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @Package: com.milla.study.netbase.expert.quartz.listener
* @Description: <启动的时候执行>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:38
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:38
* @UpdateRemark: <>
* @Version: 1.0
*/
@Component
@Order(value = 1)
public class QuartzJobInitListener implements CommandLineRunner {
@Autowired
//所有实现初始化的接口都注入进来,然后遍历执行
Map<String, QuartzJobService> scheduleJobServiceMap;
@Override
public void run(String... arg0) throws Exception {
if (scheduleJobServiceMap == null || scheduleJobServiceMap.isEmpty()) {
return;
}
Set<Map.Entry<String, QuartzJobService>> entries = scheduleJobServiceMap.entrySet();
Iterator<Map.Entry<String, QuartzJobService>> it = entries.iterator();
for (; it.hasNext(); ) {
Map.Entry<String, QuartzJobService> next = it.next();
//为防止报错,先给一个默认实现
if ("default".equals(next.getKey())) {
continue;
}
QuartzJobService service = next.getValue();
service.initSchedule();
}
}
}
微服务中,可以将每个服务中对应的任务分别启动
服务一
package com.milla.study.netbase.expert.quartz.service.impl;
import com.milla.study.netbase.expert.quartz.dto.QuartzJobDTO;
import com.milla.study.netbase.expert.quartz.enums.QuartzJobStateEnum;
import com.milla.study.netbase.expert.quartz.mapper.QuartzJobDTOMapper;
import com.milla.study.netbase.expert.quartz.service.QuartzJobService;
import com.milla.study.netbase.expert.quartz.util.QuartzManager;
import org.apache.commons.collections4.CollectionUtils;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Package: com.milla.study.netbase.expert.quartz.service.impl
* @Description: <启动的时候加载加载在运行状态的任务并启动>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:39
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:39
* @UpdateRemark: <>
* @Version: 1.0
*/
@Service("report")
public class ExampleQuartzJobOneInitServiceImpl implements QuartzJobService {
@Autowired
private QuartzManager quartzUtil;
@Autowired
private QuartzJobDTOMapper mapper;
@Override
public void initSchedule() throws SchedulerException, ClassNotFoundException {
// 获取所有报告的定时任务
List<QuartzJobDTO> jobList = mapper.selectJobByGroup("report");
if (CollectionUtils.isEmpty(jobList)) {
return;
}
for (QuartzJobDTO job : jobList) {
if (QuartzJobStateEnum.RUNNING.getCode().equals(job.getJobStatus())) {
quartzUtil.addJob(job);
}
}
}
}
服务二
package com.milla.study.netbase.expert.quartz.service.impl;
import com.milla.study.netbase.expert.quartz.dto.QuartzJobDTO;
import com.milla.study.netbase.expert.quartz.enums.QuartzJobStateEnum;
import com.milla.study.netbase.expert.quartz.mapper.QuartzJobDTOMapper;
import com.milla.study.netbase.expert.quartz.service.QuartzJobService;
import com.milla.study.netbase.expert.quartz.util.QuartzManager;
import org.apache.commons.collections4.CollectionUtils;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Package: com.milla.study.netbase.expert.quartz.service.impl
* @Description: <启动的时候加载加载在运行状态的任务并启动>
* @Author: MILLA
* @CreateDate: 2020/5/12 19:39
* @UpdateUser: MILLA
* @UpdateDate: 2020/5/12 19:39
* @UpdateRemark: <>
* @Version: 1.0
*/
@Service("report")
public class ExampleQuartzJobTwoInitServiceImpl implements QuartzJobService {
@Autowired
private QuartzManager quartzUtil;
@Autowired
private QuartzJobDTOMapper mapper;
@Override
public void initSchedule() throws SchedulerException, ClassNotFoundException {
// 获取所有报告的定时任务
List<QuartzJobDTO> jobList = mapper.selectJobByGroup("report");
if (CollectionUtils.isEmpty(jobList)) {
return;
}
for (QuartzJobDTO job : jobList) {
if (QuartzJobStateEnum.RUNNING.getCode().equals(job.getJobStatus())) {
quartzUtil.addJob(job);
}
}
}
}
Ps:表达式还需要进行学习下