spring-boot quartz定时任务

spring-boot quartz定时任务

基本功能

  1. 串并行控制
  2. 定时任务(CRUD)
  3. 定时任务启停
  4. 立即执行定时任务

相关依赖

其他缺的依赖自行引入

<!-- Quartz 这个才是最主要的 -->
<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz</artifactId>
	<version>2.3.2</version>
</dependency>

<!-- Lombok -->
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.12</version>
	<optional>true</optional>
</dependency>

<!-- commons-lang3 -->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
	<version>3.3.9</version>
</dependency>

<!-- Mybatis-plus -->
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.3.2</version>
</dependency>

<!-- Tools -->
<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-all</artifactId>
	<version>5.2.5</version>
</dependency>

<!-- Swagger ui -->
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger-ui</artifactId>
	<version>2.9.2</version>
</dependency>
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger2</artifactId>
	<version>2.9.2</version>
	<exclusions>
		<exclusion>
			<groupId>io.swagger</groupId>
			<artifactId>swagger-models</artifactId>
		</exclusion>
	</exclusions>
</dependency>

<dependency>
	<groupId>io.swagger</groupId>
	<artifactId>swagger-models</artifactId>
	<version>1.5.22</version>
</dependency>

相关代码

并行任务

QuartzJobFactory.java

import com.tld.admin.entity.business.SysJob;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

import javax.annotation.Resource;

/**
 * 计划任务执行处 无状态
 *
 * @author ming
 * @version 1.0.0
 * @date 2019/8/30 14:34
 */
public class QuartzJobFactory implements Job {

    @Resource
    private SysJobExecutor jobExecutor;

    @Override
    public void execute(JobExecutionContext context) {
        jobExecutor.invokeMethod((SysJob) context.getMergedJobDataMap().get("admin_schedule_job"));
    }
}

串行任务

QuartzJobFactoryDisallowConcurrentExecution.java

import com.tld.admin.entity.business.SysJob;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

import javax.annotation.Resource;

/**
 * 若一个方法一次执行不完下次轮转时则等待改方法执行完后才执行下一次操作
 * 该任务未串行任务
 *
 * @author ming
 * @version 1.0.0
 * @date 2019/8/30 14:34
 */
@DisallowConcurrentExecution
public class QuartzJobFactoryDisallowConcurrentExecution implements Job {

    @Resource
    private SysJobExecutor jobExecutor;

    @Override
    public void execute(JobExecutionContext context) {
        jobExecutor.invokeMethod((SysJob) context.getMergedJobDataMap().get("admin_schedule_job"));
    }

}

任务执行器

SysJobExecutor.java

import com.tld.admin.common.utils.SpringUtil;
import com.tld.admin.entity.business.SysJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 定时任务工具
 *
 * @author ming
 * @version 1.0.0
 * @date 2019/8/30 14:34
 */
@Slf4j
@Component
public class SysJobExecutor {

    /**
     * 调用SysJob中定义的方法
     *
     * @param sysJob job
     */
    public void invokeMethod(SysJob sysJob) {
        Object object = null;
        Class<?> clazz;
        if (StringUtils.isNotBlank(sysJob.getBeanClass())) {
            try {
                object = SpringUtil.getBean(sysJob.getBeanClass());
                if(ObjectUtils.isEmpty(object)){
                    log.error(String.format("任务名称 = [ %s ] --------------- 未找到该类!!!", sysJob.getJobName()));
                }
            } catch (Exception e) {
                object = null;
                e.printStackTrace();
            }
        }
        if (ObjectUtils.isEmpty(object)) {
            log.error(String.format("任务名称 = [ %s ] --------------- 未启动成功,请检查是否配置正确!!!", sysJob.getJobName()));
            return;
        }
        clazz = object.getClass();
        Method method = null;
        try {
            if (sysJob.getParams() != null && !"".equals(sysJob.getParams())) {
                method = clazz.getDeclaredMethod(sysJob.getMethodName(), String.class);
            } else {
                method = clazz.getDeclaredMethod(sysJob.getMethodName());
            }
        } catch (NoSuchMethodException e) {
            log.error(String.format("任务名称 = [ %s ] --------------- 未启动成功,方法名设置错误!!!", sysJob.getJobName()));
        } catch (SecurityException e) {
            log.error(e.getMessage(), e);
        }
        if (method != null) {
            try {
                if (sysJob.getParams() != null && !"".equals(sysJob.getParams())) {
                    method.invoke(object, sysJob.getParams());
                } else {
                    method.invoke(object);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        log.debug(String.format("任务名称 = [ %s ] ---------- 执行成功", sysJob.getJobName()));
    }

}

任务注册器

SysJobRegistrar.java

import com.tld.admin.entity.business.SysJob;
import org.quartz.*;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author ming
 * @version 1.0.0
 * @date 2020/10/12 10:29
 **/
@Component
public class SysJobRegistrar {

    @Resource
    private SchedulerFactoryBean schedulerFactoryBean;

    /**
     * 新增定时任务
     *
     * @param job job
     */
    public void addJob(SysJob job) {
        try {
            if (job == null) {
                return;
            }
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());

            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            // 不存在,创建一个
            if (null == trigger) {
                JobDetail jobDetail;
                // 判断是使用串行任务还是并行任务执行器
                if (SysJobStatus.NORMAL.getCode().equals(job.getConcurrent())) {
                    jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(job.getJobName(), job.getJobGroup()).build();
                } else {
                    jobDetail = JobBuilder.newJob(QuartzJobFactoryDisallowConcurrentExecution.class).withIdentity(job.getJobName(), job.getJobGroup()).build();
                }
                jobDetail.getJobDataMap().put("admin_schedule_job", job);
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCron());
                trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
                scheduler.scheduleJob(jobDetail, trigger);
            } else {
                // Trigger已存在,那么更新相应的定时设置
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCron());
                // 按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                // 按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void deleteJob(SysJob sysJob) {
        try {
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            JobKey jobKey = JobKey.jobKey(sysJob.getJobName(), sysJob.getJobGroup());
            scheduler.deleteJob(jobKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 立即运行任务
     *
     * @param sysJob job
     */
    public void runJobNow(SysJob sysJob) {
        try {
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            JobKey jobKey = JobKey.jobKey(sysJob.getJobName(), sysJob.getJobGroup());
            scheduler.triggerJob(jobKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 改变任务状态( 1 -> 运行中 ; 2 -> 已停止)
     *
     * @param sysJob 任务
     * @return boolean
     */
    public boolean changeJobStatus(SysJob sysJob) {
        try {
            if (SysJobStatus.NORMAL.getCode().equals(sysJob.getStatus())) {
                deleteJob(sysJob);
                return false;
            } else {
                addJob(sysJob);
                return true;
            }
        } catch (Exception e) {
            throw new RuntimeException("任务状态修改失败");
        }
    }

}

初始化定时任务

SysJobRunner.java

import com.tld.admin.entity.business.SysJob;
import com.tld.admin.service.business.SysJobService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * 初始化定时任务
 *
 * @author ming
 * @version 1.0.0
 * @date 2019/8/30
 */
@Component
@Slf4j
public class SysJobRunner implements ApplicationRunner {

    @Resource
    private SysJobService jobService;

    @Resource
    private SysJobRegistrar jobRegistrar;

    @Override
    public void run(ApplicationArguments args) {
        List<SysJob> jobList = jobService.queryNormalJob(SysJobStatus.NORMAL.getCode()).getData();
        if (!CollectionUtils.isEmpty(jobList)) {
            for (SysJob job : jobList) {
                jobRegistrar.addJob(job);
            }
            log.info("定时任务已加载完毕...");
        }else {
            log.warn("暂无可执行的任务...");
        }
    }
}

状态枚举

SysJobStatus.java

/**
 * @author ming
 * @version 1.0.0
 * @date 2020/10/11 22:31
 **/
public enum SysJobStatus {
    /**
     * 定时任务运行状态
     */
    NORMAL("运行中", "1"),
    STOPPED("已停止", "0");

    private String msg;
    private String code;

    SysJobStatus(String msg, String code) {
        this.code = code;
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

任务类

SysJobTask.java


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

/**
 * @author ming
 * @version 1.0.0
 * @date 2020/10/12 15:25
 **/
@Slf4j
@Component("sysJobTask")
public class SysJobTask {

    public void pullBlockInfoDataTask() {
        log.debug("正在执行任务==> pull_block_info_data_task <==");
        long start = System.currentTimeMillis();
        try {
            log.info("执行了任务");
            long end = System.currentTimeMillis();
            long timeConsuming = end - start;
            log.info(String.format("任务执行耗时: %s", figureOutTimeInterval(timeConsuming)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String figureOutTimeInterval(long interval) {
        //初始化Formatter的转换格式。
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
        String hms = formatter.format(interval);
        System.out.println("耗时 == " + hms);
        return hms;
    }
}

数据库字段

DROP TABLE IF EXISTS `t_sys_job`;
CREATE TABLE `t_sys_job`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '唯一标识',
  `job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '任务名',
  `job_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '任务分组',
  `cron` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'Cron表达式',
  `concurrent` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '1' COMMENT '是否并行(1 - 并行 , 2 - 串行)',
  `bean_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '执行类',
  `method_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '执行方法',
  `params` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '初始化参数',
  `remarks` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '备注',
  `creator` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '创建者ID',
  `modifier` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '修改者ID',
  `create_time` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '创建时间',
  `modify_time` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '修改时间',
  `status` varchar(1) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '1' COMMENT '执行状态(1 - 运行中 , 0 - 停止 )',
  `valid` tinyint(1) NULL DEFAULT 1 COMMENT '是否有效( 1-有效, 0-无效 )',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '定时任务' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_sys_job
-- ----------------------------
INSERT INTO `t_sys_job` VALUES (1, 'sys_task', 'sys_task', '0 */30 * * * ?', '0', 'sysJobTask', 'pullBlockInfoDataTask', '', '系统任务', NULL, NULL, NULL, NULL, '1', 1);

实体类

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.tld.admin.entity.BaseEntity;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 定时任务 实体类
 *
 * @author ming
 * @version 1.0.0
 * @date 2020-10-11 22:04:27
 **/
@Data
@ToString
@TableName("t_sys_job")
@Accessors(chain = true)
public class SysJob extends BaseEntity<SysJob> {

    /**
     * 任务名
     */
    @TableField("job_name")
    private String jobName;
    /**
     * 任务分组
     */
    @TableField("job_group")
    private String jobGroup;
    /**
     * Cron表达式
     */
    @TableField("cron")
    private String cron;
    /**
     * 执行状态(0 - 停止 ; 1 - 运行中)
     */
    @TableField("concurrent")
    private String concurrent;
    /**
     * 执行类
     */
    @TableField("bean_class")
    private String beanClass;
    /**
     * 执行方法
     */
    @TableField("method_name")
    private String methodName;
    /**
     * 初始化参数
     */
    @TableField("params")
    private String params;
    /**
     * 备注
     */
    @TableField("remarks")
    private String remarks;

    /**
     * 状态
     */
    @TableField("status")
    private String status;

    @Override
    protected Serializable pkVal() {
        return this.id;
    }

}
import cn.hutool.core.date.DatePattern;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * 基础实体
 *
 * @author m
 * @date 2020/04/16
 */
@Data
@Accessors(chain = true)
public abstract class BaseEntity<T> extends Model<BaseEntity<T>> {

    private static final long serialVersionUID = 5796049886922555842L;
    @TableId(value = "id")
    public Integer id;

    /**
     * 1 true 0 false
     */
    @TableField("valid")
    public Boolean valid;

    /**
     * 创建者
     */
    @TableField("creator")
    public String creator;

    /**
     * 最后一次修改者
     */
    @TableField("modifier")
    public String modifier;

    /**
     * 创建时间
     */
    @JSONField(format = DatePattern.NORM_DATETIME_PATTERN)
    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @TableField(value = "create_time")
    public String createTime;

    /**
     * 修改时间
     */
    @JSONField(format = DatePattern.NORM_DATETIME_PATTERN)
    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @TableField(value = "modify_time")
    public String modifyTime;

    /**
     * 查询关键字
     */
    @TableField(exist = false)
    public String searchKey;

    /**
     * 状态(0:正常;1:删除)
     */
    public static final Boolean VALID = true;
    public static final Boolean IN_VALID = false;
}

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @author ming
 * @version 1.0.0
 * @date 2020/10/12 14:06
 **/
@Data
@ApiModel(value = "后台定时任务DTO")
public class SysJobDTO {
    @ApiModelProperty(value = "任务id")
    private Integer id;
    /**
     * 任务名
     */
    @ApiModelProperty(value = "任务名称")
    private String jobName;
    /**
     * 任务分组
     */
    @ApiModelProperty(value = "任务分组")
    private String jobGroup;
    /**
     * Cron表达式
     */
    @ApiModelProperty(value = "cron表达式")
    private String cron;
    /**
     * 是否并行(0 - 否 ; 1 - 是)
     */
    @ApiModelProperty(value = "是否并行执行")
    private String concurrent;
    /**
     * 执行类
     */
    @ApiModelProperty(value = "执行类的bean")
    private String beanClass;
    /**
     * 执行方法
     */
    @ApiModelProperty(value = "方法名")
    private String methodName;
    /**
     * 初始化参数
     */
    @ApiModelProperty(value = "初始化参数")
    private String params;
    /**
     * 备注
     */
    @ApiModelProperty(value = "备注")
    private String remarks;

    /**
     * 状态 1-> 运行中, 0 -> 已停止
     */
    @ApiModelProperty(value = "任务状态")
    private String status;
}

dao

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import com.tld.admin.entity.business.SysJob;

/**
 * 定时任务 mapper
 *
 * @author m
 * @version 1.0.0
 * @date 2020-10-11 22:04:27
 **/
@Mapper
public interface SysJobMapper extends BaseMapper<SysJob> {

}

mapper

<?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.tld.admin.dao.business.SysJobMapper">

    <resultMap id="SysJobMap" type="com.tld.admin.entity.business.SysJob">
        <result column="id" property="id" />
        <result column="job_name" property="jobName" />
        <result column="job_group" property="jobGroup" />
        <result column="cron" property="cron" />
        <result column="concurrent" property="concurrent" />
        <result column="bean_class" property="beanClass" />
        <result column="method_name" property="methodName" />
        <result column="params" property="params" />
        <result column="remarks" property="remarks" />
        <result column="creator" property="creator" />
        <result column="modifier" property="modifier" />
        <result column="create_time" property="createTime" />
        <result column="modify_time" property="modifyTime" />
        <result column="status" property="status" />
        <result column="valid" property="valid" />
    </resultMap>

    
</mapper>

service

import com.baomidou.mybatisplus.extension.service.IService;
import com.tld.admin.common.handle.ApiResult;
import com.tld.admin.dto.business.SysJobDTO;
import com.tld.admin.entity.business.SysJob;

import java.util.List;

/**
 * 定时任务 Service
 *
 * @author m
 * @version 1.0.0
 * @date 2020-10-11 22:04:27
 **/
public interface SysJobService extends IService<SysJob> {

    /**
     * 查询所有正常的定时任务
     *
     * @param status 任务状态
     * @return List<SysJob>
     */
    ApiResult<List<SysJob>> queryNormalJob(String status);

    /**
     * 新增定时任务
     *
     * @param sysJob 定时任务对象
     * @return String
     */
    ApiResult<String> addNewJob(SysJobDTO sysJob);

    /**
     * 修改定时任务
     *
     * @param sysJob 定时任务对象
     * @return String
     */
    ApiResult<String> editJob(SysJobDTO sysJob);

    /**
     * 删除定时任务
     *
     * @param id 任务编号
     * @return String
     */
    ApiResult<String> deleteJob(Integer id);

    /**
     * 启停定时任务
     *
     * @param id 任务编号
     * @return String
     */
    ApiResult<String> startOrStopJob(Integer id);

    /**
     * 立即执行任务
     *
     * @param id 任务编号
     * @return String
     */
    ApiResult<String> runJobNow(Integer id);

}

impl

import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tld.admin.common.handle.ApiResult;
import com.tld.admin.config.quartz.SysJobRegistrar;
import com.tld.admin.config.quartz.SysJobStatus;
import com.tld.admin.dao.business.SysJobMapper;
import com.tld.admin.dto.business.SysJobDTO;
import com.tld.admin.entity.business.SysJob;
import com.tld.admin.service.business.SysJobService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;


/**
 * 定时任务 Impl
 *
 * @author m
 * @version 1.0.0
 * @date 2020-10-11 22:04:27
 **/
@Service
public class SysJobServiceImpl extends ServiceImpl<SysJobMapper, SysJob> implements SysJobService {

    @Resource
    private SysJobMapper jobMapper;

    @Resource
    private SysJobRegistrar jobRegistrar;

    /**
     * 查询所有正常的定时任务
     *
     * @param status 任务状态
     * @return List<SysJob>
     */
    @Override
    public ApiResult<List<SysJob>> queryNormalJob(String status) {
        List<SysJob> sysJob = jobMapper.selectList(new QueryWrapper<SysJob>().lambda()
                .eq(SysJob::getStatus, status)
                .and(queryWrapper -> queryWrapper.eq(SysJob::getValid, true)));
        return ApiResult.successOf(sysJob);
    }

    /**
     * 新增定时任务
     *
     * @param sysJob 定时任务对象
     * @return String
     */
    @Override
    public ApiResult<String> addNewJob(SysJobDTO sysJob) {
        SysJob job = jobDto2Entity(sysJob);
        job.setId(null);
        int r = jobMapper.insert(job);
        if (r <= 0) {
            return ApiResult.failOf("新增失败");
        }
        if (SysJobStatus.NORMAL.getCode().equals(sysJob.getStatus())) {
            jobRegistrar.addJob(job);
        }
        return ApiResult.successOf("新增成功");
    }

    /**
     * 修改定时任务
     *
     * @param sysJob 定时任务对象
     * @return String
     */
    @Override
    public ApiResult<String> editJob(SysJobDTO sysJob) {
        SysJob job = jobDto2Entity(sysJob);
        int r = jobMapper.updateById(job);
        if (r <= 0) {
            return ApiResult.failOf("修改失败");
        }
        SysJob existedJob = jobMapper.selectOne(new QueryWrapper<SysJob>().lambda()
                .eq(SysJob::getId, job.getId())
                .and(queryWrapper -> queryWrapper.eq(SysJob::getValid, true)));
        // 移除旧的任务
        if (SysJobStatus.NORMAL.getCode().equals(existedJob.getStatus())) {
            jobRegistrar.deleteJob(existedJob);
        }
        // 添加新的任务
        if (SysJobStatus.NORMAL.getCode().equals(job.getStatus())) {
            jobRegistrar.addJob(job);
        }
        return ApiResult.successOf("修改成功");
    }

    /**
     * 删除定时任务
     *
     * @param id 任务编号
     * @return String
     */
    @Override
    public ApiResult<String> deleteJob(Integer id) {
        SysJob existedJob = jobMapper.selectOne(new QueryWrapper<SysJob>().lambda()
                .eq(SysJob::getId, id)
                .and(queryWrapper -> queryWrapper.eq(SysJob::getValid, true)));
        existedJob.setValid(false);
        int r = jobMapper.updateById(existedJob);
        if (r <= 0) {
            return ApiResult.failOf("删除失败");
        }
        if (SysJobStatus.NORMAL.getCode().equals(existedJob.getStatus())) {
            jobRegistrar.deleteJob(existedJob);
        }
        return ApiResult.successOf("删除成功");
    }

    /**
     * 启停定时任务
     *
     * @param id 任务编号
     * @return String
     */
    @Override
    public ApiResult<String> startOrStopJob(Integer id) {
        try {
            SysJob existedJob = jobMapper.selectOne(new QueryWrapper<SysJob>().lambda()
                    .eq(SysJob::getId, id)
                    .and(queryWrapper -> queryWrapper.eq(SysJob::getValid, true)));

            if (!jobRegistrar.changeJobStatus(existedJob)) {
                existedJob.setStatus(SysJobStatus.STOPPED.getCode());
                int i = jobMapper.updateById(existedJob);
                if (i <= 0) {
                    return ApiResult.successOf("关闭失败");
                }
                return ApiResult.successOf("关闭成功");
            } else {
                existedJob.setStatus(SysJobStatus.NORMAL.getCode());
                int i = jobMapper.updateById(existedJob);
                if (i <= 0) {
                    return ApiResult.successOf("开启失败");
                }
                return ApiResult.successOf("开启成功");
            }
        } catch (Exception e) {
            return ApiResult.failOf(e.getMessage());
        }
    }

    /**
     * 立即执行任务(由于其他原因导致的任务挂掉,但是数据库状态没有修改的情况下,来重启任务)
     *
     * @param id 任务编号
     * @return String
     */
    @Override
    public ApiResult<String> runJobNow(Integer id) {
        SysJob sysJob = jobMapper.selectOne(new QueryWrapper<SysJob>().lambda()
                .eq(SysJob::getId, id)
                .and(queryWrapper -> queryWrapper.eq(SysJob::getValid, true)));
        if (ObjectUtils.isEmpty(sysJob)) {
            return ApiResult.failOf("任务执行失败");
        }

        jobRegistrar.runJobNow(sysJob);
        return ApiResult.failOf("任务执行成功");
    }

    private static SysJob jobDto2Entity(SysJobDTO sysJob) {
        SysJob job = new SysJob();
        job.setJobName(sysJob.getJobName())
                .setJobGroup(sysJob.getJobGroup())
                .setStatus(sysJob.getStatus())
                .setConcurrent(sysJob.getConcurrent())
                .setBeanClass(sysJob.getBeanClass())
                .setCron(sysJob.getCron())
                .setMethodName(sysJob.getMethodName())
                .setParams(sysJob.getParams())
                .setRemarks(sysJob.getRemarks())
                .setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)))
                .setId(sysJob.getId());
        return job;
    }
}

controller

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tld.admin.annotation.SysLog;
import com.tld.admin.common.handle.ApiResult;
import com.tld.admin.dto.business.SysJobDTO;
import com.tld.admin.entity.business.SysJob;
import com.tld.admin.service.business.SysJobService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * 定时任务 控制层
 *
 * @author ming
 * @version 1.0.0
 * @date 2020-10-11 22:04:27
 **/
@RestController
@RequestMapping("job")
@Api(tags = "定时任务模块")
public class SysJobController {

    @Resource
    private SysJobService sysJobService;

    @GetMapping()
    //@RequiresPermissions("job:list")
    @ApiOperation(value = "定时任务列表")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "当前页码", name = "current", dataType = "int", paramType = "query", defaultValue = "1"),
            @ApiImplicitParam(value = "分页大小", name = "size", dataType = "int", paramType = "query", defaultValue = "10")
    })
    public ApiResult fetchJobs(@RequestParam(required = false, defaultValue = "1") Integer current,
                               @RequestParam(required = false, defaultValue = "10") Integer size) {
        Page<SysJob> page = sysJobService.page(new Page<>(current, size), new QueryWrapper<SysJob>().lambda().eq(SysJob::getValid, true));
        return ApiResult.successOf(page);
    }

    @PostMapping()
    //@RequiresPermissions("job:add")
    @ApiOperation(value = "新增定时任务")
    @SysLog(value = "新增用户", type = 1)
    public ApiResult addJob(@ModelAttribute SysJobDTO sysJob) {
        return sysJobService.addNewJob(sysJob);
    }

    @PutMapping()
    //@RequiresPermissions("job:edit")
    @ApiOperation(value = "修改定时任务")
    public ApiResult editJob(@ModelAttribute SysJobDTO sysJob) {
        return sysJobService.editJob(sysJob);
    }

    @DeleteMapping("/{id}")
    //@RequiresPermissions("job:delete")
    @ApiOperation(value = "删除定时任务")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "任务编号", name = "id", dataType = "int", paramType = "path"),
    })
    public ApiResult deleteJob(@PathVariable("id") Integer id) {
        return sysJobService.deleteJob(id);
    }

    @PutMapping("/{id}")
    //@RequiresPermissions("job:status")
    @ApiOperation(value = "启停定时任务")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "任务编号", name = "id", dataType = "int", paramType = "path"),
    })
    public ApiResult startOrStopJob(@PathVariable("id") Integer id) {
        return sysJobService.startOrStopJob(id);
    }

    @PutMapping("execution/{id}")
    //@RequiresPermissions("job:execution")
    @ApiOperation(value = "立即执行定时任务")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "任务编号", name = "id", dataType = "int", paramType = "path"),
    })
    public ApiResult runJobNow(@PathVariable("id") Integer id) {
        return sysJobService.runJobNow(id);
    }
}
posted @ 2020-10-13 14:06  itwetouch  阅读(297)  评论(0编辑  收藏  举报