崛起於Springboot2.0.X之手動配置Quartz定時任務(47)

    (記得來開源中國關注我喲!若是博客被我發現有很差的地方,都會優化更新的,因此關注我呦,嘻嘻)前端

      技術棧:Springboot2.0.X(2.1.X也能夠)+ Quartz +FastMybatis (自認爲比mybatis-plus更方便的框架) + Hutool + lombok vue

      FastMybatis框架博客:java

                0一、崛起於Springboot2.0.X之入門FastMybatis--> my.oschina.net/mdxlcj/blog/1835665 mysql

                0二、崛起於Springboot2.0.X之整合FastMybatis精裝版 --> my.oschina.net/mdxlcj/blog/3059687git

                0三、FastMybatis框架快速入門 --> 官方文檔web

      Quartz入門級框架博客:spring

                0四、崛起於Springboot2.0.X之集成Quartz定時調度 --> my.oschina.net/mdxlcj/blog/1862472sql

      序言:以前公司有一個需求說是能夠經過一個界面來操做定時任務的時間、包括修改、啓動、關閉等功能,而不是在代碼中寫死,那個時候從網上找了好久都沒有找到,博客都特別初級,只能算是入門的後來就不了了之了,目前已經實現開發出這套功能,公開一下,我也但願可以幫助更多的人在企業更加快速的實現該功能,如圖:數據庫

       而後咱們看一下,新增定時任務配置截圖:express

    這個功能也有批量暫停定時任務的功能、當即恢復、以及執行,固然還有定時任務啓動時的日誌記錄,如圖:

    因此接下來就進入開發階段,因爲前端頁面是用vue寫的,我就不把前端代碼弄出來了,反而這樣會讓你們使用起來比較費力,因此咱們就不用vue進行測試了,只用後段本身生成數據來測試就能夠了,也可以達到目的的。

一、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>

二、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

三、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='定時任務日誌'

四、實體類

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";
    }
}

五、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());
        }
    }
}

六、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);
}

七、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;
   }
}

八、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;
    }
}

九、定時任務

        該類涉及到@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("該定時任務由前臺頁面控制什麼時候啓動");
    }
}

十、啓動測試

        謹記,啓動類,千萬不要添加@MapperScan(),由於集成了FastMybatis框架,已經自動封裝了。若是你們不喜歡這個框架的話,也可使用Mybatis或者流行的Mybatis-plus或者TKMybatis、EasyMybatis等等框架。

        測試接口:http://localhost:8081/schedule/save,個人端口是8081的。

         結果如圖已經觸發咱們剛剛寫的定時任務了:

     成功啦!不喜歡用FastMybatis的話用其餘框架操做mysql吧,畢竟我不太喜歡用mybatis-plus,畢竟須要多寫代碼。        

相關文章
相關標籤/搜索