springboot整合Quartz实现定时管理

对于定时,简单点只要一个注解就可以搞定了

import org.springframework.scheduling.annotation.Scheduled;
@Scheduled(cron = "0 0 2 1 * ?")

这个注解是要引用在代码里面的,也就是说如果想要改变执行的时间就要去改代码,如果在业务改动很频繁的情况下这种方法就很不可取了,Quartz正好可以避免这个情况,可以通过前台功能来控制增删改查,执行,暂停等功能,下面就是整合的全过程

先声明一下,我的环境为springboot+mybatisplus+maven

第一步,先引入需要依赖的jar包,pom.xml中配置

<!-- Quartz定时任务 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

第二步,application.yml中配置(超时忍受时间设置为100毫秒)

# 定时任务
  quartz:
    # 任务信息存储至数据库
    job-store-type: jdbc
    properties:
      org:
        quartz:
          jobStore:
            misfireThreshold: 100

第三步:创建数据库表(表名是Quartz封装好的,不能改动,创建执行有顺序,批量执行不成功可以单个执行)

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;


CREATE TABLE QRTZ_JOB_DETAILS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(200) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_SIMPLE_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CRON_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    CRON_EXPRESSION VARCHAR(200) NOT NULL,
    TIME_ZONE_ID VARCHAR(80),
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_SIMPROP_TRIGGERS
  (          
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    STR_PROP_1 VARCHAR(512) NULL,
    STR_PROP_2 VARCHAR(512) NULL,
    STR_PROP_3 VARCHAR(512) NULL,
    INT_PROP_1 INT NULL,
    INT_PROP_2 INT NULL,
    LONG_PROP_1 BIGINT NULL,
    LONG_PROP_2 BIGINT NULL,
    DEC_PROP_1 NUMERIC(13,4) NULL,
    DEC_PROP_2 NUMERIC(13,4) NULL,
    BOOL_PROP_1 VARCHAR(1) NULL,
    BOOL_PROP_2 VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_BLOB_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    BLOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CALENDARS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    CALENDAR_NAME  VARCHAR(200) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_FIRED_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    FIRED_TIME BIGINT(13) NOT NULL,
    SCHED_TIME BIGINT(13) NOT NULL,
    PRIORITY INTEGER NOT NULL,
    STATE VARCHAR(16) NOT NULL,
    JOB_NAME VARCHAR(200) NULL,
    JOB_GROUP VARCHAR(200) NULL,
    IS_NONCONCURRENT VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);

CREATE TABLE QRTZ_SCHEDULER_STATE
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);

CREATE TABLE QRTZ_LOCKS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME  VARCHAR(40) NOT NULL, 
    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);

//这个表的表名可以改变,字段尽量不要去更改
CREATE TABLE `t_quartz_job` (
  `id` varchar(255) NOT NULL,
  `create_by` varchar(255) DEFAULT '' COMMENT '创建人',
  `create_time` datetime DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
  `del_flag` int(11) DEFAULT '0' COMMENT '软删除 0正常 1删除',
  `update_by` varchar(255) DEFAULT '' COMMENT '操作人',
  `update_time` datetime DEFAULT '0000-00-00 00:00:00' COMMENT '操作时间',
  `cron_expression` varchar(255) DEFAULT '' COMMENT 'cron表达式',
  `description` varchar(255) DEFAULT '' COMMENT '备注',
  `job_class_name` varchar(255) DEFAULT '' COMMENT '任务类名',
  `parameter` varchar(255) DEFAULT '' COMMENT '参数',
  `status` int(11) DEFAULT '0' COMMENT '状态 0正常 -1停止',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='定时任务'

第四步:功能逻辑(我这里只给出了对于Quartz调度器的增删改查,项目的实际逻辑根据项目要求来)

@RequestMapping(value = "/add",method = RequestMethod.POST)
@ApiOperation(value = "添加定时任务")
public Result<Object> addJob(@ModelAttribute QuartzJob job){
    
   //定时类名都是唯一的,逻辑中最好加上验证(job.getJobClassName()为执行路径,需要执行的文件的项目路径)
   List<QuartzJob> list = quartzJobService.findByJobClassName(job.getJobClassName());
   if(list!=null&&list.size()>0){
       return new ResultUtil<Object>().setErrorMsg("该定时任务类名已存在");
   }
    //在Quartz调度器中添加定时
   add(job.getJobClassName(),job.getCronExpression(),job.getParameter());
    //自己的业务逻辑
   quartzJobService.save(job);
   return new ResultUtil<Object>().setSuccessMsg("创建定时任务成功");
}

@RequestMapping(value = "/edit",method = RequestMethod.POST)
@ApiOperation(value = "更新定时任务")
public Result<Object> editJob(@ModelAttribute QuartzJob job){
    //修改就要先把构造器中原有存储的删掉
    delete(job.getJobClassName());
    //删掉原有的在新增
    add(job.getJobClassName(),job.getCronExpression(),job.getParameter());
    //自己的业务逻辑
    job.setStatus(0);//更新后默认给0
    quartzJobService.update(job);
    return new ResultUtil<Object>().setSuccessMsg("更新定时任务成功");
}

@RequestMapping(value = "/pause",method = RequestMethod.POST)
@ApiOperation(value = "暂停定时任务")
public Result<Object> pauseJob(@ModelAttribute QuartzJob job){
    try {
        //暂停构造器定时任务
        scheduler.pauseJob(JobKey.jobKey(job.getJobClassName()));
    } catch (SchedulerException e) {
            throw new MyException("暂停定时任务失败");
    }
    //自己的业务逻辑
    job.setStatus(-1);//状态 0正常 -1停止
    quartzJobService.update(job);
    return new ResultUtil<Object>().setSuccessMsg("暂停定时任务成功")
}

@RequestMapping(value = "/resume",method = RequestMethod.POST)
@ApiOperation(value = "恢复定时任务")
public Result<Object> resumeJob(@ModelAttribute QuartzJob job){
    try {
        //恢复构造器定时任务
        scheduler.resumeJob(JobKey.jobKey(job.getJobClassName()));
    } catch (SchedulerException e) {
        throw new MyException("恢复定时任务失败");
    }
    //自己的业务逻辑
    job.setStatus(0);
    quartzJobService.update(job);
    return new ResultUtil<Object>().setSuccessMsg("恢复定时任务成功");
}

    @RequestMapping(value = "/delByIds",method = RequestMethod.POST)
    @ApiOperation(value = "删除定时任务")
    public Result<Object> deleteJob(String ids){
        QuartzJob job = quartzJobService.get(ids);
        //删除构造器定时任务
        delete(job.getJobClassName());
        quartzJobService.delete(job.getId());
        return new ResultUtil<Object>().setSuccessMsg("删除定时任务成功");
    }

    /**
     * 添加构造器定时任务
     * @param jobClassName
     * @param cronExpression
     * @param parameter
     */
    public void add(String jobClassName, String cronExpression, String parameter){

        try {
            // 启动调度器
            scheduler.start();

            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
                    .withIdentity(jobClassName)
                    .usingJobData("parameter",parameter)
                    .build();

            //表达式调度构建器(即任务执行的时间) 使用withMisfireHandlingInstructionDoNothing() 忽略掉调度暂停过程中没有执行的调度
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();

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

            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.error(e.toString());
            throw new MyException("创建定时任务失败");
        } catch (Exception e){
            throw new MyException("后台找不到该类名任务");
        }
    }

    /**
     * 删除构造器定时任务
     * @param jobClassName
     */
    public void delete(String jobClassName){

        try {
            scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
            scheduler.deleteJob(JobKey.jobKey(jobClassName));
        } catch (Exception e) {
            throw new MyException("删除定时任务失败");
        }
    }

    public static Job getClass(String classname) throws Exception {
        Class<?> class1 = Class.forName(classname);
        return (Job)class1.newInstance();
    }

第五步:定时执行类

package com.shangze.szxs.quartz;


import com.shangze.szxs.sever.service.MemberSignInService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

// 一定要引用job,在内置execute()方法内调用自己的定时逻辑,在添加构造器定时任务是的jobClassName 字段的值就是com.shangze.szxs.quartz.TimedEditMemberSignInContinuityDay,路径一定不要丢到,不然就找不到了
@Slf4j
public class TimedEditMemberSignInContinuityDay implements Job {

    @Autowired
    private MemberSignInService memberSignInService;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("*************更改会员连签天数定时开始时间************"+new Date());
        System.out.println("*************更改会员连签天数定时开始时间************"+new Date());

        memberSignInService.editContinuityDay();

        log.info("*************更改会员连签天数定时结束时间************"+new Date());
        System.out.println("*************更改会员连签天数结束开始时间************"+new Date());
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值