【SpringBoot】廿五、SpringBoot中使用Quartz管理定
时任务
2020-07-21 15:55:47
定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 Token 信息等等,之前我们都是在项目中规定这个定时任务什么时候启动,到时间了便会自己启动,那么我们想要停止这个定时任务的时候,就需要去改动代码,还得启停服务器,这是非常不友好的事情
直至遇见 Quartz,利用图形界面可视化管理定时任务,使得我们对定时任务的管理更加方便,快捷
一、Quartz 简介
Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中。它提供了巨大的灵 活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB作业预构 建,JavaMail及其它,支持cron-like表达式等等。
二、开发前戏
1、引入 maven 依赖
这里引入了 web 的依赖,以及 Quartz 的依赖,其余依赖请根据需求自行引入
2、创建数据表
数据模型:
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;
/** *
* 定时任务信息表 *
** @author lizhou * @since 2020-07-21 */ @Data
@EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName(\"sys_quartz\")
@ApiModel(value=\"SysQuartz对象\定时任务信息表\") public class SysQuartz extends Model @ApiModelProperty(value = \"主键id\") @TableId(value = \"id\ 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 下面我们就要完成定时任务的 新增、修改、删除、启停 等基本操作了,由于不是很复杂,这里的代码就不贴出来了,贴几张图吧 列表页: 新增页: 四、定时任务 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、页面添加定时任务 添加定时任务 那么我们的任务类名就是:com.zyxx.sbm.job.TestJob cron 表达式:/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; /** * * 定时任务信息表 服务实现类 * * @author lizhou * @since 2020-07-21 */ @Slf4j @Service public class SysQuartzServiceImpl extends ServiceImpl @Autowired private Scheduler scheduler; /** * 添加定时任务 */ @Override public ResponseResult add(SysQuartz sysQuartz) { 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\(); // 表达式调度构建器(即任务执行的时间) 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】十九、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 queryWrapper.eq(\"quartz_status\ 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 管理定时任务的学习就到这儿了,其实也并不难理解,相比于之前用的定时任务是不是好很多了呢,别忘了最后加上系统启动任务哦 如您在阅读中发现不足,欢迎留言!!!
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- gamedaodao.net 版权所有 湘ICP备2024080961号-6
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务