崛起于Springboot2.0.X之页面统一操作Quartz所有定时任务何时启动(47)

蹲街弑〆低调 提交于 2019-11-28 18:40:44

    (记得来开源中国关注我哟!如果博客被我发现有不好的地方,都会优化更新的,所以关注我呦,嘻嘻)

      技术栈:Springboot2.0.X(2.1.X也可以)+ Quartz +FastMybatis (自认为比mybatis-plus更方便的框架) + Hutool + lombok 

      FastMybatis框架博客:

                01、崛起于Springboot2.0.X之入门FastMybatis--> my.oschina.net/mdxlcj/blog/1835665 

                02、崛起于Springboot2.0.X之整合FastMybatis精装版 --> my.oschina.net/mdxlcj/blog/3059687

                03、FastMybatis框架快速入门 --> 官方文档

      Quartz入门级框架博客:

                04、崛起于Springboot2.0.X之集成Quartz定时调度 --> my.oschina.net/mdxlcj/blog/1862472

      序言:之前公司有一个需求说是可以通过一个界面来操作定时任务的时间、包括修改、启动、关闭等功能,而不是在代码中写死,那个时候从网上找了很久都没有找到,博客都特别初级,只能算是入门的后来就不了了之了,目前已经实现开发出这套功能,公开一下,我也希望能够帮助更多的人在企业更加快速的实现该功能,如图:

       然后我们看一下,新增定时任务配置截图:

    这个功能也有批量暂停定时任务的功能、立即恢复、以及执行,当然还有定时任务启动时的日志记录,如图:

    所以接下来就进入开发阶段,由于前端页面是用vue写的,我就不把前端代码弄出来了,反而这样会让大家使用起来比较费力,所以我们就不用vue进行测试了,只用后段自己生成数据来测试就可以了,也能够达到目的的。

1、pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>4.6.1</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
    <groupId>net.oschina.durcframework</groupId>
    <artifactId>fastmybatis-spring-boot-starter</artifactId>
    <version>1.8.1</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

2、application.properties

mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ss?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

3、mysql表结构

CREATE TABLE `schedule_job` (
  `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务id',
  `bean_name` varchar(200) DEFAULT NULL COMMENT 'spring bean名称',
  `method_name` varchar(100) DEFAULT NULL COMMENT '方法名',
  `params` varchar(2000) DEFAULT NULL COMMENT '参数',
  `cron_expression` varchar(100) DEFAULT NULL COMMENT 'cron表达式',
  `status` tinyint(4) DEFAULT NULL COMMENT '任务状态 0:启动 1:搁置', 
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`job_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='定时任务'


CREATE TABLE `schedule_job_log` (
  `log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务日志id',
  `job_id` bigint(20) NOT NULL COMMENT '任务id',
  `bean_name` varchar(200) DEFAULT NULL COMMENT 'spring bean名称',
  `method_name` varchar(100) DEFAULT NULL COMMENT '方法名',
  `params` varchar(2000) DEFAULT NULL COMMENT '参数',
  `status` tinyint(4) NOT NULL COMMENT '任务状态    0:成功    1:失败',
  `error` varchar(2000) DEFAULT NULL COMMENT '失败信息',
  `times` int(11) NOT NULL COMMENT '耗时(单位:毫秒)',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`log_id`),
  KEY `job_id` (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='定时任务日志'

4、实体类

import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@Data
@Table(name = "schedule_job")
public class ScheduleJobEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY"; //任务调度参数key
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "job_id")
    private Long jobId;            //任务id
    @Column(name = "bean_name")
    private String beanName;       //spring bean名称
    @Column(name = "method_name")
    private String methodName;     //方法名
    @Column(name = "params")
    private String params;         //参数
    @Column(name = "cron_expression")
    private String cronExpression; //cron表达式
    @Column(name = "status")
    private Integer status;        //任务状态
    @Column(name = "remark")
    private String remark;         //备注
    @Column(name = "create_time")
    private Date createTime;       //创建时间
}
import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * 定时执行日志
 */
@Data
@Table(name = "schedule_job_log")
public class ScheduleJobLogEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "log_id")
    private Long logId;       //日志id
    @Column(name = "job_id")
    private Long jobId;       //任务id
    @Column(name = "bean_name")
    private String beanName;  //spring bean名称
    @Column(name = "method_name")
    private String methodName;//方法名
    @Column(name = "params")
    private String params;    //参数
    @Column(name = "status")
    private Integer status;   // 任务状态    0:成功    1:失败
    @Column(name = "error")
    private String error;     //失败信息
    @Column(name = "times")
    private Integer times;    //耗时(单位:毫秒)
    @Column(name = "create_time")
    private Date createTime;  //创建时间
}

    请求接口统一返回实体类

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
@Data
@AllArgsConstructor
@ToString
public class ResultData {
    private boolean success;
    private String code;
    private String message;
    private Object data;

    public ResultData() {
        this.success = true;
        this.code = "200";
    }
}

5、Util层

        这一层代码大家看不明白没有关系,毕竟这些都是工具类里面的,不是我们开发日常编码那种,所以只需要配置一次就好啦,正常开发我们就直接跳过第五步就好了。

import org.apache.commons.lang.StringUtils;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class ScheduleJob extends QuartzJobBean {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private ExecutorService service = Executors.newSingleThreadExecutor();

    @Override
    protected void executeInternal(JobExecutionContext context) {
        ScheduleJobEntity scheduleJob = (ScheduleJobEntity) context.getMergedJobDataMap()
                .get(ScheduleJobEntity.JOB_PARAM_KEY);

        //获取spring bean
        ScheduleJobService scheduleJobService = (ScheduleJobService) SpringContextUtils.getBean("scheduleJobService");

        //数据库保存执行记录
        ScheduleJobLogEntity log = new ScheduleJobLogEntity();
        log.setJobId(scheduleJob.getJobId());
        log.setBeanName(scheduleJob.getBeanName());
        log.setMethodName(scheduleJob.getMethodName());
        log.setParams(scheduleJob.getParams());
        log.setCreateTime(new Date());

        //任务开始时间
        long startTime = System.currentTimeMillis();

        try {
            //执行任务
            logger.info("任务准备执行,任务ID:" + scheduleJob.getJobId());
            ScheduleRunnable task = new ScheduleRunnable(scheduleJob.getBeanName(),
                    scheduleJob.getMethodName(), scheduleJob.getParams());
            Future<?> future = service.submit(task);

            future.get();

            //任务执行总时长
            long times = System.currentTimeMillis() - startTime;
            log.setTimes((int) times);
            //任务状态    0:成功    1:失败
            log.setStatus(0);

            logger.info("任务执行完毕,任务ID:" + scheduleJob.getJobId() + "  总共耗时:" + times + "毫秒");
        } catch (Exception e) {
            logger.error("任务执行失败,任务ID:" + scheduleJob.getJobId(), e);

            //任务执行总时长
            long times = System.currentTimeMillis() - startTime;
            log.setTimes((int) times);

            //任务状态    0:成功    1:失败
            log.setStatus(1);
            log.setError(StringUtils.substring(e.toString(), 0, 2000));
        } finally {
            scheduleJobService.saveLog(log);
        }
    }
}
import org.apache.commons.lang.StringUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

public class ScheduleRunnable implements Runnable {
    private Object target;
    private Method method;
    private String params;

    public ScheduleRunnable(String beanName, String methodName, String params) throws NoSuchMethodException, SecurityException {
        this.target = SpringContextUtils.getBean(beanName);
        this.params = params;

        if (StringUtils.isNotBlank(params)) {
            this.method = target.getClass().getDeclaredMethod(methodName, String.class);
        } else {
            this.method = target.getClass().getDeclaredMethod(methodName);
        }
    }

    @Override
    public void run() {
        try {
            ReflectionUtils.makeAccessible(method);
            if (StringUtils.isNotBlank(params)) {
                method.invoke(target, params);
            } else {
                method.invoke(target);
            }
        } catch (Exception e) {
            throw new RuntimeException("执行定时任务失败", e);
        }
    }
}
import org.quartz.*;

public class ScheduleUtils {
    private final static String JOB_NAME = "TASK_";

    /**
     * 获取触发器key
     */
    public static TriggerKey getTriggerKey(Long jobId) {
        return TriggerKey.triggerKey(JOB_NAME + jobId);
    }

    /**
     * 获取jobKey
     */
    public static JobKey getJobKey(Long jobId) {
        return JobKey.jobKey(JOB_NAME + jobId);
    }

    /**
     * 获取表达式触发器
     */
    public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) {
        try {
            return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("获取定时任务CronTrigger出现异常", e);
        }
    }

    /**
     * 创建定时任务
     */
    public static void createScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
        try {
            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getJobId())).build();

            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
                    .withMisfireHandlingInstructionDoNothing();

            //按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getJobId())).withSchedule(scheduleBuilder).build();

            //放入参数,运行时的方法可以获取
            jobDetail.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);

            scheduler.scheduleJob(jobDetail, trigger);

            //暂停任务
            if (scheduleJob.getStatus() == 1) {
                pauseJob(scheduler, scheduleJob.getJobId());
            }
        } catch (SchedulerException e) {
            throw new RuntimeException("创建定时任务失败", e);
        }
    }

    /**
     * 更新定时任务
     */
    public static void updateScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
        try {
            TriggerKey triggerKey = getTriggerKey(scheduleJob.getJobId());

            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
                    .withMisfireHandlingInstructionDoNothing();

            CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getJobId());

            //按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

            //参数
            trigger.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);

            scheduler.rescheduleJob(triggerKey, trigger);

            //暂停任务
            if (scheduleJob.getStatus() == 1) {
                pauseJob(scheduler, scheduleJob.getJobId());
            }

        } catch (SchedulerException e) {
            throw new RuntimeException("更新定时任务失败", e);
        }
    }

    /**
     * 立即执行任务
     */
    public static void run(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
        try {
            //参数
            JobDataMap dataMap = new JobDataMap();
            dataMap.put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);

            scheduler.triggerJob(getJobKey(scheduleJob.getJobId()), dataMap);
        } catch (SchedulerException e) {
            throw new RuntimeException("立即执行定时任务失败", e);
        }
    }

    /**
     * 暂停任务
     */
    public static void pauseJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.pauseJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("暂停定时任务失败", e);
        }
    }

    /**
     * 恢复任务
     */
    public static void resumeJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.resumeJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("暂停定时任务失败", e);
        }
    }

    /**
     * 删除定时任务
     */
    public static void deleteScheduleJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.deleteJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("删除定时任务失败", e);
        }
    }
}
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtils implements ApplicationContextAware {
    public static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }

    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    public static <T> T getBean(String name, Class<T> requiredType) {
        return applicationContext.getBean(name, requiredType);
    }

    public static boolean containsBean(String name) {
        return applicationContext.containsBean(name);
    }

    public static boolean isSingleton(String name) {
        return applicationContext.isSingleton(name);
    }

    public static Class<? extends Object> getType(String name) {
        return applicationContext.getType(name);
    }

    /**
     * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
     */
    public static <T> T getBean(Class<T> requiredType) {
        return applicationContext.getBean(requiredType);
    }
}
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;


public class ValidatorUtils {
    private static Validator validator;

    static {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    /**
     * 校验对象
     *
     * @param object 待校验对象
     * @param groups 待校验的组
     * @throws BusinessException 校验不通过,则报BusinessException异常
     */
    public static void validateEntity(Object object, Class<?>... groups)
            throws RuntimeException {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            ConstraintViolation<Object> constraint = (ConstraintViolation<Object>) constraintViolations.iterator().next();
            throw new RuntimeException(constraint.getMessage());
        }
    }
}

6、dao层

import com.gitee.fastmybatis.core.mapper.CrudMapper;
import java.util.List;
import java.util.Map;

public interface ScheduleJobDao extends CrudMapper<ScheduleJobEntity,Integer> {
    int updateBatchStatus(Map<String, Object> map);
    List<ScheduleJobEntity> queryList(Map<String, Object> map);
    ScheduleJobEntity queryObject(Long jobId);
    int queryTotal(Map<String, Object> map);
    void deleteBatch(Long[] jobIds);
}
import com.gitee.fastmybatis.core.mapper.CrudMapper;

public interface ScheduleJobLogDao extends CrudMapper<ScheduleJobLogEntity,Long> {
    ScheduleJobLogEntity queryObject(Long jobId);
}

7、Service层

    接口

public interface ScheduleJobService {

    /**
     * 根据ID,查询定时任务
     */
    ScheduleJobEntity queryObject(Long jobId);

    /**
     * 查询定时任务列表
     */
    List<ScheduleJobEntity> queryList(Map<String, Object> map);

    /**
     * 查询总数
     */
    int queryTotal(Map<String, Object> map);

    /**
     * 保存定时任务
     */
    void save(ScheduleJobEntity scheduleJob);

    /**
     * 更新定时任务
     */
    void update(ScheduleJobEntity scheduleJob);

    /**
     * 批量删除定时任务
     */
    void deleteBatch(Long[] jobIds);

    /**
     * 批量更新定时任务状态
     */
    int updateBatch(Long[] jobIds, int status);

    /**
     * 立即执行
     */
    void run(Long[] jobIds);

    /**
     * 暂停运行
     */
    void pause(Long[] jobIds);

    /**
     * 恢复运行
     */
    void resume(Long[] jobIds);

    /**
     * 定时任务列表+总数
     */
    ResultData listJob(int pageIndex, int pageSize);

    /**
     * 日志查询
     */
    ResultData queryLogObject(Long jobId);

    /**
     * 保存日志记录
     */
    void saveLog(ScheduleJobLogEntity log);

    /**
     * 查询日志记录列表
     */
    ResultData listLog(int pageIndex, int pageSize);
}

    实现类

import com.gitee.fastmybatis.core.query.Query;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("scheduleJobService")
public class ScheduleJobServiceImpl implements ScheduleJobService {
   @Autowired
    private Scheduler scheduler;

   @Autowired
   private ScheduleJobDao schedulerJobDao;

   @Autowired
   ScheduleJobLogDao jobLogDao;
   
   /**
    * 项目启动时,初始化定时器
    */
   @PostConstruct
   public void init(){
      List<ScheduleJobEntity> scheduleJobList = schedulerJobDao.queryList(new HashMap<>());
      for(ScheduleJobEntity scheduleJob : scheduleJobList){
         CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getJobId());
            //如果不存在,则创建
            if(cronTrigger == null) {
                ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
            }else {
                ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
            }
      }
   }
   
   @Override
   public ScheduleJobEntity queryObject(Long jobId) {
      return schedulerJobDao.queryObject(jobId);
   }

   @Override
   public List<ScheduleJobEntity> queryList(Map<String, Object> map) {
      return schedulerJobDao.queryList(map);
   }

   @Override
   public int queryTotal(Map<String, Object> map) {
      return schedulerJobDao.queryTotal(map);
   }


   @Override
   @Transactional
   public void save(ScheduleJobEntity scheduleJob) {
      schedulerJobDao.save(scheduleJob);
        ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
    }
   
   @Override
   @Transactional
   public void update(ScheduleJobEntity scheduleJob) {
        ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
        schedulerJobDao.update(scheduleJob);
    }

   @Override
   @Transactional
    public void deleteBatch(Long[] jobIds) {
       for(Long jobId : jobIds){
          ScheduleUtils.deleteScheduleJob(scheduler, jobId);
       }
       //删除数据
       schedulerJobDao.deleteBatch(jobIds);
   }

   @Override
    public int updateBatch(Long[] jobIds, int status){
       Map<String, Object> map = new HashMap<>();
       map.put("list", jobIds);
       map.put("status", status);
       return schedulerJobDao.updateBatchStatus(map);
    }
    
   @Override
   @Transactional
    public void run(Long[] jobIds) {
       for(Long jobId : jobIds){
          ScheduleUtils.run(scheduler, queryObject(jobId));
       }
    }

   @Override
   @Transactional
    public void pause(Long[] jobIds) {
        for(Long jobId : jobIds){
          ScheduleUtils.pauseJob(scheduler, jobId);
       }
       updateBatch(jobIds, 1);
    }

   @Override
   @Transactional
    public void resume(Long[] jobIds) {
       for(Long jobId : jobIds){
          ScheduleUtils.resumeJob(scheduler, jobId);
       }
       updateBatch(jobIds, 0);
    }

   @Override
   public ResultData listJob(int pageIndex, int pageSize) {
      ResultData resultData = new ResultData();
      //查询列表数据
      Query query = new Query();
      query.page(1,10);

      List<ScheduleJobEntity> jobList = schedulerJobDao.list(query);

      long total = schedulerJobDao.getCount(query);

      Map<String,Object> map = new HashMap<>();
      map.put("total",total);
      map.put("list",jobList);

      resultData.setData(map);
      return resultData;
   }

   @Override
   public ResultData queryLogObject(Long jobId) {
      ResultData resultData = new ResultData();
      resultData.setData(jobLogDao.getById(jobId));
      return resultData;
   }

   @Override
   public void saveLog(ScheduleJobLogEntity log) {
      jobLogDao.save(log);
   }

   @Override
   public ResultData listLog(int pageIndex, int pageSize) {
      ResultData resultData = new ResultData();

      //查询列表数据
      Query query = new Query();
      query.page(pageIndex,pageSize);

      List<ScheduleJobLogEntity> jobList = jobLogDao.list(query);

      long total = jobLogDao.getCount(query);

      Map<String,Object> map = new HashMap<>();
      map.put("total",total);
      map.put("list",jobList);

      resultData.setData(map);

      return resultData;
   }
}

8、Controller层

@RestController
@RequestMapping("/schedule")
public class ScheduleJobController {

    @Autowired
    private ScheduleJobService scheduleJobService;

    /**
     * 定时任务列表
     */
    @RequestMapping("/list")
    public ResultData list() {
        return scheduleJobService.listJob(1,10);
    }

    /**
     * 定时任务信息
     */
    @RequestMapping("/info/{jobId}")
    public ResultData info(@PathVariable("jobId") Long jobId) {
        ScheduleJobEntity schedule = scheduleJobService.queryObject(jobId);
        ResultData resultData = new ResultData();
        resultData.setData(schedule);

        return resultData;

    }

    /**
     * 保存定时任务 @RequestBody ScheduleJobEntity scheduleJob
     */
    @RequestMapping("/save")
    public ResultData save() {

        //先测试编写一个临时ScheduleJobEntity,毕竟后端页面不会写
        ScheduleJobEntity jobEntity = createJob();
        ValidatorUtils.validateEntity(jobEntity);

        scheduleJobService.save(jobEntity);

        return new ResultData();
    }

    /**
     * 修改定时任务
     */
    @RequestMapping("/update")
    public ResultData update(@RequestBody ScheduleJobEntity scheduleJob) {
        ValidatorUtils.validateEntity(scheduleJob);

        scheduleJobService.update(scheduleJob);
        return new ResultData();
    }

    /**
     * 删除定时任务
     */
    @RequestMapping("/delete")
    public ResultData delete(@RequestBody Long[] jobIds) {
        scheduleJobService.deleteBatch(jobIds);
        return new ResultData();
    }

    /**
     * 立即执行任务
     */
    @RequestMapping("/run")
    public ResultData run(@RequestBody Long[] jobIds) {
        scheduleJobService.run(jobIds);
        return new ResultData();
    }

    /**
     * 暂停定时任务
     */
    @RequestMapping("/pause")
    public ResultData pause(@RequestBody Long[] jobIds) {
        scheduleJobService.pause(jobIds);
        return new ResultData();
    }

    /**
     * 恢复定时任务
     */
    @RequestMapping("/resume")
    public ResultData resume(@RequestBody Long[] jobIds) {
        scheduleJobService.resume(jobIds);
        return new ResultData();
    }

    /**
     * 定时任务日志列表
     */
    @RequestMapping("/log/list")
    public ResultData listLog() {
       return scheduleJobService.listLog(1,10);
    }

    /**
     * 定时任务日志信息查询
     */
    @RequestMapping("/log/info/{logId}")
    public ResultData infoLog(@PathVariable("logId") Long logId) {
        return scheduleJobService.queryLogObject(logId);
    }

    public static ScheduleJobEntity createJob(){
        ScheduleJobEntity jobEntity = new ScheduleJobEntity();
        jobEntity.setBeanName("mytask");
        jobEntity.setCreateTime(new Date());
        jobEntity.setMethodName("firstTask");
        jobEntity.setCronExpression("0/10 * * * * ?");
        jobEntity.setParams(null);
        jobEntity.setStatus(1);
        jobEntity.setRemark("测试该定时任务的执行");
        return jobEntity;
    }
}

9、定时任务

        该类涉及到@Component(value = "mytask")和方法名都将被前端页面使用,使用这两个属性值定位到何时执行该定时任务。

import org.springframework.stereotype.Component;

/**
 * @Author:MuJiuTian
 * @Description: 页面控制定时任务的触发时间、开启和关闭都要有定时任务
 * @Date: Created in 下午2:06 2019/8/27
 */
@Component(value = "mytask")
public class MyTask {

    public void firstTask(){
        //再这个方法中执行task业务逻辑
        System.out.println("该定时任务由前台页面控制何时启动");
    }
}

10、启动测试

        谨记,启动类,千万不要添加@MapperScan(),因为集成了FastMybatis框架,已经自动封装了。如果大家不喜欢这个框架的话,也可以使用Mybatis或者流行的Mybatis-plus或者TKMybatis、EasyMybatis等等框架。

        测试接口:http://localhost:8081/schedule/save,我的端口是8081的。

         结果如图已经触发我们刚刚写的定时任务了:

     成功啦!不喜欢用FastMybatis的话用其他框架操作mysql吧,毕竟我不太喜欢用mybatis-plus,毕竟需要多写代码。        

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!