SpringBoot中使用Quartz管理定时任务

SpringBoot中使用Quartz管理定时任务定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 Token 信息等等,之前我们都是在项目中规定这个定时任务什么时

大家好,欢迎来到IT知识分享网。

定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 Token 信息等等,之前我们都是在项目中规定这个定时任务什么时候启动,到时间了便会自己启动,那么我们想要停止这个定时任务的时候,就需要去改动代码,还得启停服务器,这是非常不友好的事情

直至遇见 Quartz,利用图形界面可视化管理定时任务,使得我们对定时任务的管理更加方便,快捷

一、Quartz 简介

Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中。它提供了巨大的灵 活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB作业预构 建,JavaMail及其它,支持cron-like表达式等等。

二、开发前戏

1、引入 maven 依赖

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

这里引入了 web 的依赖,以及 Quartz 的依赖,其余依赖请根据需求自行引入

2、创建数据表

数据模型:

SpringBoot中使用Quartz管理定时任务

SQL语句:

drop table if exists sys_quartz; /*==============================================================*/ /* Table: sys_quartz */ /*==============================================================*/ create table sys_quartz (    id                   bigint(20) not null auto_increment comment '主键id',    class_name varchar(32) comment '任务类名',    cron_expression varchar(32) comment 'cron表达式',    param varchar(32) comment '参数',    descript varchar(11) comment '描述',    quartz_status varchar(255) comment '启动状态(0--启动1--停止)',    create_time datetime comment '创建时间',    create_user bigint(20) comment '创建人',    status               tinyint(1) default 0 comment '状态(0--正常1--停用)',    del_flag tinyint(1) default 0 comment '删除状态(0,正常,1已删除)',    primary key (id) ) type = InnoDB; alter table sys_quartz comment '定时任务信息表';

三、开发进行中

1、创建实体类

import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.zyxx.common.annotation.Dict; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; /**  * <p>  * 定时任务信息表  * </p>  *  * @author lizhou  * @since 2020-07-21  */ @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName("sys_quartz") @ApiModel(value="SysQuartz对象", description="定时任务信息表") public class SysQuartz extends Model<SysQuartz> {     @ApiModelProperty(value = "主键id")     @TableId(value = "id", type = IdType.AUTO)     private Long id;     @ApiModelProperty(value = "任务类名")     @TableField("class_name")     private String className;     @ApiModelProperty(value = "cron表达式")     @TableField("cron_expression")     private String cronExpression;     @ApiModelProperty(value = "参数")     @TableField("param")     private String param;     @ApiModelProperty(value = "描述")     @TableField("descript")     private String descript;     @ApiModelProperty(value = "启动状态(0--启动1--停止)")     @TableField("quartz_status")     private Integer quartzStatus;     @ApiModelProperty(value = "状态(0--正常1--停用)")     @TableField("status")     private Integer status;     @ApiModelProperty(value = "删除状态(0--未删除1--已删除)")     @TableField("del_flag")     @TableLogic     private Integer delFlag;     @ApiModelProperty(value = "创建者")     @TableField("create_user")     private Long createUser;     @ApiModelProperty(value = "创建时间")     @TableField("create_time")     private String createTime;     @Override     protected Serializable pkVal() {         return this.id;     } }

2、实现定时任务的 CRUD

下面我们就要完成定时任务的 新增、修改、删除、启停 等基本操作了,由于不是很复杂,这里的代码就不贴出来了,贴几张图吧

列表页:

SpringBoot中使用Quartz管理定时任务

新增页:

SpringBoot中使用Quartz管理定时任务

四、定时任务

1、定时任务类

我们把定时任务都放在 job 包下面,一个定时任务就是一个文件,写一个测试的类 TestJob.java

import com.zyxx.common.utils.DateUtils; import lombok.extern.slf4j.Slf4j; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /**  * @ClassName TestJob  * 测试定时任务  * @Author Lizhou  * @Date 2020-07-21 10:58:58  **/ @Slf4j public class TestJob implements Job {     @Override     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {         System.out.println("定时任务启动:" + DateUtils.getYmdHms());     } }

TestJob 这个类实现了 Job 接口,实现了 execute 方法,这里还可以接收参数

这个文件在 com.zyxx.sbm.job 包下面,那么在页面新增定时任务的时候,就需要填写任务类名为:com.zyxx.sbm.job.TestJob

cron 表达式的知识这里就不一一介绍了

2、页面添加定时任务

SpringBoot中使用Quartz管理定时任务

那么我们的任务类名就是:com.zyxx.sbm.job.TestJobcron 表达式:*/2 * * * * ?,表示两秒钟执行一次参数:我们没有传入参数

3、后台添加定时任务

package com.zyxx.sbm.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.zyxx.common.shiro.SingletonLoginUtils; import com.zyxx.common.utils.DateUtils; import com.zyxx.common.utils.LayTableResult; import com.zyxx.common.utils.ResponseResult; import com.zyxx.sbm.entity.SysQuartz; import com.zyxx.sbm.mapper.SysQuartzMapper; import com.zyxx.sbm.service.SysQuartzService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /**  * <p>  * 定时任务信息表 服务实现类  * </p>  *  * @author lizhou  * @since 2020-07-21  */ @Slf4j @Service public class SysQuartzServiceImpl extends ServiceImpl<SysQuartzMapper, SysQuartz> implements SysQuartzService {     @Autowired     private Scheduler scheduler;   /**   * 添加定时任务   */     @Override     public ResponseResult add(SysQuartz sysQuartz) {         QueryWrapper<SysQuartz> queryWrapper = new QueryWrapper<>();         queryWrapper.eq("class_name", sysQuartz.getClassName());         List<SysQuartz> sysQuartzList = list(queryWrapper);         if (null != sysQuartzList && !sysQuartzList.isEmpty()) {             return ResponseResult.getInstance().error("该任务类名已经存在");         }         sysQuartz.setCreateTime(DateUtils.getYmdHms());         sysQuartz.setCreateUser(SingletonLoginUtils.getUserId());         save(sysQuartz);         // 启动         if (0 == sysQuartz.getQuartzStatus()) {             this.schedulerAdd(sysQuartz.getClassName().trim(), sysQuartz.getCronExpression().trim(), sysQuartz.getParam());         }         return ResponseResult.getInstance().success();     }     /**      * 添加定时任务      *      * @param className      * @param cronExpression      * @param param      */     @Override     public void schedulerAdd(String className, String cronExpression, String param) {         try {             // 启动调度器             scheduler.start();             // 构建job信息             JobDetail jobDetail = JobBuilder.newJob(getClass(className).getClass()).withIdentity(className).usingJobData("param", param).build();             // 表达式调度构建器(即任务执行的时间)             CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);             // 按新的cronExpression表达式构建一个新的trigger             CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(className).withSchedule(scheduleBuilder).build();             scheduler.scheduleJob(jobDetail, trigger);         } catch (SchedulerException e) {             log.error(e.getMessage());         } catch (RuntimeException e) {             log.error(e.getMessage());         } catch (Exception e) {             log.error(e.getMessage());         }     }     /**      * 删除定时任务      *      * @param className      */     @Override     public void schedulerDelete(String className) {         try {             scheduler.pauseTrigger(TriggerKey.triggerKey(className));             scheduler.unscheduleJob(TriggerKey.triggerKey(className));             scheduler.deleteJob(JobKey.jobKey(className));         } catch (Exception e) {             log.error(e.getMessage(), e);         }     }     private static Job getClass(String className) throws Exception {         Class<?> class1 = Class.forName(className);         return (Job) class1.newInstance();     } }

需要注入 Scheduler 对象,使用该对象开启或停止定时任务

在启动定时任务之前,我们应先删除该任务类名开启的定时任务,防止该任务类名已经添加过了

// 删除定时任务 schedulerDelete(sysQuartz.getClassName().trim()); // 添加定时任务 schedulerAdd(sysQuartz.getClassName().trim(), sysQuartz.getCronExpression().trim(), sysQuartz.getParam());

添加定时任务,传入任务类名,cron 表达式,参数

停止定时任务,只需要:

scheduler.pauseJob(JobKey.jobKey(sysQuartz.getClassName().trim()));

根据任务类名,停止定时任务即可

五、开发测试

启动项目,在管理界面,开启定时任务,即可在控制台看到打印的信息

SpringBoot中使用Quartz管理定时任务

表示我们的定时任务已经启动成功了

六、优化建议

当我们添加了定时任务并启动后,重新启动项目的时候,定时任务却不会自动启动,这时候,我们就需要在项目启动的时候做一些事情了,也就是系统启动任务

不清楚的同学可以复习一下之前我的博客【SpringBoot】十九、SpringBoot中实现启动任务

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zyxx.sbm.entity.SysQuartz; import com.zyxx.sbm.service.SysQuartzService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.List; /**  * @ClassName SystemStartTask  * 项目启动任务--启动定时任务  * @Author Lizhou  * @Date 2020-07-21 12:56:56  **/ @Component @Order(100) public class SystemQuartzStartTask implements CommandLineRunner {     @Autowired     private SysQuartzService sysQuartzService;     @Override     public void run(String... args) throws Exception {         // 查询启动的定时任务         QueryWrapper<SysQuartz> queryWrapper = new QueryWrapper<>();         queryWrapper.eq("status", 0);         queryWrapper.eq("quartz_status", 0);         List<SysQuartz> list = sysQuartzService.list(queryWrapper);         if (null != list && !list.isEmpty()) {             for (SysQuartz item : list) {                 // 删除定时任务                 sysQuartzService.schedulerDelete(item.getClassName().trim());                 // 添加定时任务                 sysQuartzService.schedulerAdd(item.getClassName().trim(), item.getCronExpression().trim(), item.getParam());             }         }     } }

从数据库查询出启动的定时任务,并将他们添加到定时任务启动中,这样项目一启动时,就会自动启动我们定义的定时任务了

最后

任务类名的正则表达式

/^[a-zA-Z]+(\.([a-zA-Z])+)+$/

cron 表达式的验证使用正则太麻烦,可以使用 Quartz 自带验证方法

CronExpression.isValidExpression(cron)

SpringBoot 中使用 Quartz 管理定时任务的学习就到这儿了,其实也并不难理解,相比于之前用的定时任务是不是好很多了呢,别忘了最后加上系统启动任务哦

如您在阅读中发现不足,欢迎留言!!!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:

https://blog.csdn.net/_/article/details/

SpringBoot中使用Quartz管理定时任务

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/49891.html

(0)
上一篇 2024-08-28 11:26
下一篇 2024-08-29 19:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信