springBoot2整合Quartz动态任务

如果使用 springboot 内置的 TaskScheduler 定时任务实现动态任务,请阅读

最近项目用到Quartz,所以花了几天时间折腾下,记录一下,送给刚接触且迷茫的小伙伴,分别介绍2种方式
Quartz的表不用多说,要么去官网下载,要么去包里找 D:\web\apache-maven-repository\org\quartz-scheduler\quartz\2.3.2\quartz-2.3.2.jar!\org\quartz\impl\jdbcjobstore\tables_mysql_innodb.sql,然后执行一下脚本即可。

我在项目里是做成了一个自定义的 task-spring-boot-starter,方便其他地方使用,引入依赖


    io.github.chichengyu
    task-spring-boot-starter
    1.3.3.RELEASE

即可使用。下面进入正题

一:jpa

导包:



     org.springframework.boot
     spring-boot-starter-quartz


     mysql
     mysql-connector-java
     5.1.41

再看配置 application.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/quartz?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT
    username: root
    password: 123456
  quartz:
    job-store-type: jdbc
    jdbc:
      initialize-schema: never

ok了,没错就是这么简单的配置,然后写一个定时任务执行一下就可以持久化到数据库

重点说下第二种,

二:jdbc

导包:



     org.springframework.boot
     spring-boot-starter-data-jdbc



     org.springframework.boot
     spring-boot-starter-quartz


     mysql
     mysql-connector-java
     5.1.41

配置 application.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/quartz?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT
    username: root
    password: 123456

首先创建一个工具类 SpringContextUtils.java

package com.example.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Spring Context 工具类
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {

    private 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 getBean(Class clazz){
        return applicationContext.getBean(clazz);
    }

    public static T getBean(String name,Class 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 getType(String name){
        return applicationContext.getType(name);
    }
}

接着创建 Quartz 配置类 QuartzConfig.java,内容中的方式一、方式二差效果都一样,本人比较喜欢第一种,不多说,爽,哈哈

package com.example.job;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * Quartz配置
 */
@Configuration
@EnableScheduling
public class QuartzConfig {

    /*********************************** 方式一 start **************************************/
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setDataSource(dataSource);
        //quartz参数
        Properties prop = new Properties();
        prop.put("org.quartz.scheduler.instanceName", "TaskScheduler");
        prop.put("org.quartz.scheduler.instanceId", "AUTO");
        //线程池配置
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "20");
        prop.put("org.quartz.threadPool.threadPriority", "5");
        //JobStore配置
        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        //集群配置
        prop.put("org.quartz.jobStore.isClustered", "false");// 集群时一定要设置为 true
        prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
        prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");

        prop.put("org.quartz.jobStore.misfireThreshold", "12000");
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
        prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");

        //PostgreSQL数据库,需要打开此注释
        //prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate");

        /* 使用动态注入数据源
        prop.put("org.quartz.jobStore.dataSource","qzDS");
        prop.put("org.quartz.dataSource.qzDS.driver","com.mysql.jdbc.Driver");
        prop.put("org.quartz.dataSource.qzDS.URL","jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
        prop.put("org.quartz.dataSource.qzDS.user","root");
        prop.put("org.quartz.dataSource.qzDS.password","123456");
        prop.put("org.quartz.dataSource.qzDS.maxConnections","60");*/

        factory.setQuartzProperties(prop);

        factory.setSchedulerName("TaskScheduler");
        //延时启动
        factory.setStartupDelay(30);
        factory.setApplicationContextSchedulerContextKey("applicationContextKey");
        //可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
        factory.setOverwriteExistingJobs(true);
        //设置自动启动,默认为true
        factory.setAutoStartup(true);

        return factory;
    }
    /*********************************** 方式一 end **************************************/

    //-------------------------------------------------------------------------------------

    /*********************************** 方式二 start **************************************/
    /*@Bean
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setQuartzProperties(quartzProperties());
        return factory;
    }

    @Bean
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
        //在quartz.properties中的属性被读取并注入后再初始化对象
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }*/

    /**
     * quartz初始化监听器
     */
    /*@Bean
    public QuartzInitializerListener executorListener() {
        return new QuartzInitializerListener();
    }*/

    /**
     * 通过SchedulerFactoryBean获取Scheduler的实例
     */
    /*@Bean(name = "Scheduler")
    public Scheduler scheduler() throws IOException {
        return schedulerFactoryBean().getScheduler();
    }*/
    /*********************************** 方式二 end **************************************/
}

继续创建定时任务执行Bean QuartzJob.java 继承 Quartz 的 QuartzJobBean

package com.example.job;

import com.example.job.pojo.TaskJobEntity;
import com.example.job.pojo.TaskJobLogEntity;
import com.example.service.TaskJobLogService;
import com.example.util.R;
import com.example.util.SpringContextUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * 定时任务
 */
@DisallowConcurrentExecution//上次任务没有执行完,下次任务推迟执行
public class QuartzJob extends QuartzJobBean {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        TaskJobEntity taskJobEntity = (TaskJobEntity) jobExecutionContext.getMergedJobDataMap().get(TaskJobEntity.JOB_PARAM_KEY);
        logger.info("定时器参数,{}",taskJobEntity);

        // 获取日志服务对象Bean
        TaskJobLogService logService = SpringContextUtils.getBean(TaskJobLogService.class);
        //数据库保存执行记录
        TaskJobLogEntity logEntity = new TaskJobLogEntity();
        logEntity.setJobId(taskJobEntity.getJobId());
        logEntity.setBeanName(taskJobEntity.getBeanName());
        logEntity.setParams(taskJobEntity.getParams());
        logEntity.setCreateTime(new Date());

        // 任务开始执行时间
        long startTime = System.currentTimeMillis();
        try {
            //执行任务
            logger.debug("任务准备执行,任务ID:" + taskJobEntity.getJobId());

            Object target = SpringContextUtils.getBean(taskJobEntity.getBeanName());
            Method method = target.getClass().getDeclaredMethod("run", String.class);
            R result = (R)method.invoke(target,taskJobEntity.getParams());

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

            //任务状态    0:成功    1:失败
            logEntity.setTimes((int) times);
            logEntity.setStatus(0);
            if (null != result) {
                logEntity.setStatus(result.getCode());
                logEntity.setMessage(result.getMsg());
            }
            logger.debug("任务执行完毕,任务ID:" + taskJobEntity.getJobId() + "  总共耗时:" + times + "毫秒");
        } catch (Exception e) {
            logger.error("任务执行失败,任务ID:" + taskJobEntity.getJobId(), e);

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

            // 任务状态    0:成功  1:失败  记录数据库
            logEntity.setTimes((int)times);
            logEntity.setStatus(1);
            logEntity.setError(e.toString());
        }finally {
            // 最终记录到数据库
            logService.save(logEntity);
        }
    }
}

继续创建一个工具-定时任务管理 QuartzJobManager.java,包含任务的添加更新删除暂停执行方法

package com.example.job;

import com.example.job.pojo.TaskJobEntity;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 定时任务管理
 */
@Component
public class QuartzJobManager {
    // 前缀
    private final String JOB_NAME = "TASK_";

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;
    //@Autowired
    //private Scheduler scheduler;

    /**
     * 获取调度器
     * @return
     */
    public Scheduler getScheduler(){
        return schedulerFactoryBean.getScheduler();
    }

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

    /**
     * 获取 triggerKey
     * @param jobId
     * @return
     */
    public TriggerKey getTriggerKey(Long jobId){
        return TriggerKey.triggerKey(JOB_NAME + jobId);
    }

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

    /**
     * 创建任务
     * @param taskJobEntity 任务实体类(对应自定义的数据库任务表)
     * @return Date 返回创建任务成功后执行时间
     */
    public Date createScheduleJob(TaskJobEntity taskJobEntity){
        try {
            // 1.获取调度器 Scheduler
            Scheduler scheduler = getScheduler();
            // 2.定义 jobDetail(构建job信息)
            JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class).withIdentity(getJobKey(taskJobEntity.getJobId())).build();
            // 3.定义trigger(按新的cronExpression表达式构建一个新的trigger)
            // 不触发立即执行,等待下次Cron触发频率到达时刻开始按照Cron频率依次执行  withMisfireHandlingInstructionDoNothing
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(taskJobEntity.getCronExpression()).withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(taskJobEntity.getJobId())).withSchedule(cronScheduleBuilder).build();
            // 放入参数,运行时的方法可以获取
            jobDetail.getJobDataMap().put(TaskJobEntity.JOB_PARAM_KEY,taskJobEntity);
            // 4.执行
            Date startTime = scheduler.scheduleJob(jobDetail,trigger);
            // 暂停任务
            if (taskJobEntity.getStatus() == 1){// 0表示继续,1表示暂停
                pauseJob(taskJobEntity.getJobId());
            }
            return startTime;
        } catch (SchedulerException e) {
            throw new RuntimeException("创建定时任务失败",e);
        }
    }

    /**
     * 更新定时任务
     * @param taskJobEntity 任务实体类(对应自定义的数据库任务表)
     * @return Date 返回更新任务成功后执行时间
     */
    public Date updateScheduleJob(TaskJobEntity taskJobEntity){
        try {
            TriggerKey triggerKey = getTriggerKey(taskJobEntity.getJobId());
            // 1.获取调度器 Scheduler
            Scheduler scheduler = getScheduler();
            // 2.获取 cron 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(taskJobEntity.getCronExpression()).withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = getCronTrigger(scheduler, taskJobEntity.getJobId());
            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            // 放入参数,运行时的方法可以获取
            trigger.getJobDataMap().put(TaskJobEntity.JOB_PARAM_KEY,taskJobEntity);
            // 3.执行
            Date updateTime = scheduler.rescheduleJob(triggerKey,trigger);
            // 暂停任务
            if (taskJobEntity.getStatus() == 1){// 0表示继续,1表示暂停
                pauseJob(taskJobEntity.getJobId());
            }
            return updateTime;
        } catch (SchedulerException e) {
            throw new RuntimeException("更新定时任务失败",e);
        }
    }

    /**
     * 立即执行(让定时任务立即执行,**注意:暂停状态下的定时任务,如果立即执行,只会执行一次,相当于一次性执行)
     * @param taskJobEntity 任务实体类(对应自定义的数据库任务表)
     */
    public void run(TaskJobEntity taskJobEntity){
        try {
            // 参数
            JobDataMap dataMap = new JobDataMap();
            dataMap.put(TaskJobEntity.JOB_PARAM_KEY,taskJobEntity);

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

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

    /**
     * 恢复任务
     * @param jobId 任务jobId
     */
    public void resumeJob(Long jobId){
        try {
            getScheduler().resumeJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("恢复定时任务失败",e);
        }
    }

    /**
     * 验证定时任务是否存在
     * @param jobId 任务id
     * @return
     */
    public boolean check(Long jobId){
        try {
            return getScheduler().checkExists(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("验证定时任务是否存在失败",e);
        }
    }

    /**
     * 删除定时任务
     * @param jobId 定时任务id
     */
    public void deleteScheduleJob(Long jobId){
        // 1.获取调度器 Scheduler
        Scheduler scheduler = getScheduler();
        try {
            // 2.暂停触发器
            scheduler.pauseTrigger(getTriggerKey(jobId));
            // 3.删除触发器
            scheduler.unscheduleJob(getTriggerKey(jobId));
            // 4.删除任务
            scheduler.deleteJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("删除定时任务失败",e);
        }
    }
}

别急,还没完,继续创建接口 ITask.java,这个接口的作用就是,需要添加定时器时只需要实现该接口即可(如:需要多个定时器,只需要创建多个类来实现该接口

package com.example.job.task;

import com.example.util.R;

/**
 * 定时任务接口,所有定时任务都要实现该接口
 */
public interface ITask {

    /**
     * 执行定时任务接口
     * @param params   参数,多参数使用JSON数据
     * @return R
     */
    R run(String params);
}

接口内容很简单吧,就一个待实现方法,好了,到此基本完成了,接下来创建一个测试定时器 TestTask,注意了,这个测试定时器只需要实现定时器接口 ITask.java,并实现 run方法,注意:该名称必须与我们自定义的定时器表中的 Bean 名称一致

package com.example.job.task;

import com.example.util.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 测试定时器
 */
@Slf4j
@Component("testTask") // 该名称必须与我们自定义的定时器表中的 Bean 名称一致
public class TestTask implements ITask{

    /**
     * 执行定时任务接口
     * @param params 参数,多参数使用JSON数据
     * @return R
     */
    @Override
    public R run(String params) {
        log.info("测试定时器任务执行了,{}",params);
        return R.success("ok");
    }
}

ok了到此,大功告成。现在只需要创建一个测试控制器来添加一个测试定时控制器TestController.java添加删除暂停我们的定时任务就可以了

package com.example.job;

import com.example.job.pojo.TaskJobEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * 测试定时器
 */
@RestController
public class TestController {

    @Autowired
    private QuartzJobManager quartzJobManager;

    @GetMapping("/check")
    public String testQuartzCheck(){
        boolean res1 = quartzJobManager.check(100L);
        boolean res2 = quartzJobManager.check(200L);
        boolean res3 = quartzJobManager.check(300L);
        return "ok:验证任务是否存在," + res1 + "," + res2 + "," + res3;
    }

    @GetMapping("/addjob")
    public String testQuartzAdd() {
        TaskJobEntity taskJobEntity = new TaskJobEntity();
        taskJobEntity.setBeanName("testTask");
        taskJobEntity.setJobId(100L);
        taskJobEntity.setStatus(0);
        taskJobEntity.setParams("我是测试定时器");
        taskJobEntity.setCronExpression("*/2 * * * * ?");
        taskJobEntity.setRemark("测试");
        taskJobEntity.setCreateTime(new Date());

        Date startTime = quartzJobManager.createScheduleJob(taskJobEntity);
        return "ok:开始时间," + startTime;
    }

    @GetMapping("/updatejob")
    public String testQuartzUpdate(){
        TaskJobEntity taskJobEntity = new TaskJobEntity();
        taskJobEntity.setBeanName("testTask");
        taskJobEntity.setJobId(100L);
        taskJobEntity.setStatus(0);
        taskJobEntity.setParams("修改-我是测试定时器");
        taskJobEntity.setCronExpression("*/10 * * * * ?");
        taskJobEntity.setRemark("修改-测试");
        taskJobEntity.setCreateTime(new Date());
        Date updateTime = quartzJobManager.updateScheduleJob(taskJobEntity);
        return "ok:修改成功,时间," + updateTime;
    }

    @GetMapping("/runjob")
    public String testQuartzRunJob(){
        TaskJobEntity taskJobEntity = new TaskJobEntity();
        taskJobEntity.setBeanName("testTask");
        taskJobEntity.setJobId(100L);
        taskJobEntity.setStatus(0);
        taskJobEntity.setParams("立即执行-我是测试定时器");
        taskJobEntity.setCronExpression("*/2 * * * * ?");
        taskJobEntity.setRemark("立即执行-测试");
        taskJobEntity.setCreateTime(new Date());
        quartzJobManager.run(taskJobEntity);
        return "ok:立即执行成功";
    }

    @GetMapping("/pausejob")
    public String testQuartzPauseJob(){
        quartzJobManager.pauseJob(100L);
        return "ok:暂停成功";
    }

    @GetMapping("/resumejob")
    public String testQuartzResumeJob(){
        quartzJobManager.resumeJob(100L);
        return "ok:恢复成功";
    }

    @GetMapping("/delete")
    public String testQuartzDelete(){
        quartzJobManager.deleteScheduleJob(100L);
        return "ok:删除成功";
    }
}

到此彻底完成了,好了,启动springBoot,访问接口,查看是不是定时器是不是成功了,再看数据库是不是已经有记录了,恭喜你。

提供一下Quartz实现中用到的自定义的两张表实体类R类

自定义的两张表 定时器表 task_job定时器日志表 task_job_log

CREATE TABLE `task_job` (
  `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务id',
  `bean_name` varchar(200) DEFAULT NULL COMMENT 'spring bean名称',
  `params` text 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=5 DEFAULT CHARSET=utf8 COMMENT='定时任务';

CREATE TABLE `task_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名称',
  `params` text COMMENT '参数',
  `status` tinyint(4) NOT NULL COMMENT '任务状态    0:成功    1:失败',
  `message` text COMMENT '正常信息',
  `error` text COMMENT '失败信息',
  `times` int(11) NOT NULL COMMENT '耗时(单位:毫秒)',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`log_id`),
  KEY `job_id` (`job_id`),
  KEY `create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='定时任务日志';

对应的实体类

package com.example.job.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * 定时任务
 */
@Data
public class TaskJobEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    
    /**
     * 任务调度参数key
     */
    public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";
    
    /**
     * 任务id
     */
    private Long jobId;

    /**
     * spring bean名称
     */
    private String beanName;
    
    /**
     * 参数
     */
    private String params;
    
    /**
     * cron表达式
     */
    private String cronExpression;

    /**
     * 任务状态
     */
    private Integer status;

    /**
     * 备注
     */
    private String remark;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
}

日志实体类

package com.example.job.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * 定时任务日志
 */
@Data
public class TaskJobLogEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    
    /**
     * 日志id
     */
    private Long logId;
    
    /**
     * 任务id
     */
    private Long jobId;
    
    /**
     * spring bean名称
     */
    private String beanName;
    
    /**
     * 参数
     */
    private String params;
    
    /**
     * 任务状态    0:成功    1:失败
     */
    private Integer status;
    
    /**
     * 正常信息
     */
    private String message;
    
    /**
     * 失败信息
     */
    private String error;
    
    /**
     * 耗时(单位:毫秒)
     */
    private Integer times;
    
    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
}

用到的 R.java

package com.example.util;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.Serializable;

/**
 * 返回数据类
 * @param 
 */
//保证序列化json的时候,如果是null的对象,key也会消失
//@JsonInclude(Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class R implements Serializable {
    // 成功值
     private static final int SUCCESS_CODE = 0;
    // 失败值
     private static final int ERROR_CODE = 1;

    //状态码
    private int code;
    //消息
    private String msg;
    //返回数据
    private T data;

    private R(int code){
        this.code = code;
    }
    private R(int code, T data){
        this.code = code;
        this.data = data;
    }
    private R(int code, String msg){
        this.code = code;
        this.msg = msg;
    }
    private R(int code, String msg, T data){
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static  R success(){
        return new R(SUCCESS_CODE,"success");
    }
    public static  R success(String msg){
        return new R(SUCCESS_CODE,msg);
    }
    public static  R success(T data){
        return new R(SUCCESS_CODE,data);
    }
    public static  R success(String msg, T data){
        return new R(SUCCESS_CODE,msg,data);
    }

    public static  R error(){
        return new R(ERROR_CODE,"error");
    }
    public static  R error(String msg){
        return new R(ERROR_CODE,msg);
    }
    public static  R error(int code, String msg){
        return new R(code,msg);
    }

    public int getCode(){
        return code;
    }
    public String getMsg(){
        return msg;
    }
    public T getData(){
        return data;
    }
}

你可能感兴趣的:(springBoot2整合Quartz动态任务)