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

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

一、Quartz 简介

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

二、开发前戏

1、引入 maven 依赖

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-quartz

这里引入了 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对象", description="定时任务信息表")

public class SysQuartz extends Model {

@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

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

列表页:

新增页:

四、定时任务

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 implements SysQuartzService {

@Autowired

private Scheduler scheduler;

/**

* 添加定时任务

*/

@Override

public ResponseResult add(SysQuartz sysQuartz) {

QueryWrapper queryWrapper = new QueryWrapper<>();

queryWrapper.eq("class_name", sysQuartz.getClassName());

List 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】十九、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 = new QueryWrapper<>();

queryWrapper.eq("status", 0);

queryWrapper.eq("quartz_status", 0);

List 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 管理定时任务的学习就到这儿了,其实也并不难理解,相比于之前用的定时任务是不是好很多了呢,别忘了最后加上系统启动任务哦

总结

到此这篇关于SpringBoot中使用Quartz管理定时任务的文章就介绍到这了,更多相关SpringBoot管理定时任务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

java quartz管理,SpringBoot中使用Quartz管理定时任务的方法相关推荐

  1. 【学习笔记】springBoot中获取sping管理的bean

    文章目录 一.使用场景 二.springBoot中获取sping管理的bean 2.1 生成工具类SpringContextUtil 2.2 使用工具类SpringContextUtil 2.3 注意 ...

  2. 【SpringBoot】面试必杀技-泰山陨石坠,SpringBoot中主启动类的run方法启动流程是什么?

    开头导语由Chatgpt完成 当今互联网行业中,Java后端开发岗位的竞争异常激烈,对于面试者来说,掌握一些技巧和知识点将有助于脱颖而出.而对于SpringBoot框架的使用和运行机制,更是Java后 ...

  3. java 控制器 返回 json_SpringMVC中controller返回json数据的方法

    java 控制器 返回 json_SpringMVC中controller返回json数据的方法 1.方法一: 使用springmvc原生注解@ResponseBody @ResponseBody @ ...

  4. SpringBoot中实现quartz定时任务

    Quartz整合到SpringBoot(持久化到数据库) 背景 最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于 ...

  5. SpringBoot中整合Quartz

    场景 项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/35688 简介 Quartz是OpenSymphony开源组织在Jo ...

  6. 超简单的Springboot中的日志管理配置

    本案例中可以了解,怎么配置日志的输出路径,输出格式(比如说zip格式),按日期进行划分(今天的日志输出为一个文件,明天的日志输出到另一个文件),在按日期划分的同时又按文件大小划分(比如说每天的日志记录 ...

  7. Java笔记-对SpringBoot中CommandLineRunner的使用笔记

    从中可以看到,这个是SpringBoot中的一个接口,他是在Spring环境都建起了后,一个一个的调用,都是在主线程中调用,如下: 事例代码如下: DisposeOne.java @Component ...

  8. java filter注入,Spring-boot中Filter注入bean

    Spring-boot中Filter注入bean 在spring中使用Filter的方式不用再多说,但是通常情况下我们在使用filter中都可能会注入部分配置的类或者部分具有特殊功能的业务类. 在这种 ...

  9. IDEA中运行项目时 java: -source 1.5 中不支持 diamond 运算符 解决方法

    说在前面的话: 前段时间更新了IDEA,从2019版本更新到了2020版本,之前在2019版运行好好的项目在2020版本中突然出现了 java: -source 1.5 中不支持 diamond 运算 ...

最新文章

  1. 将iPad, iPhone直投屏幕用于TEASOFT课程录制
  2. 机器人学 —— 机器人视觉(极几何)
  3. 如何使处于不同局域网的计算机实现远程通信_小区自来水二次加压泵站远程监控系统方案...
  4. VS2008 只生成DLL不生成lib文件
  5. 服务器系统性能计数器,MSRS 2008 Windows Service 性能对象的性能计数器
  6. tranmac不能识别_U盘插入苹果mac系统不能识别的解决方法
  7. PVE虚拟服务器配置,我与PVE的交往史 篇一:如何使用虚拟机PVE一步一步打造自己想要的ALL IN ONE 主机...
  8. 树莓派 4B 配置 Ubuntu20.04 和 ROS2
  9. vscode代码对比差异视图窗口切换方法(左右文件位置切换)
  10. python中class什么意思_python中的class是什么意思
  11. linux ui 布局管理器,第1组UI组件:布局管理器
  12. easywechat微信开发系列(2):公众号网页支付
  13. 国内外证券交易系统开发平台比较
  14. 悲剧收场的梅耶尔给雅虎留下了哪些“遗产”?
  15. God‘s Perspective - God View - 上帝视角
  16. 11.18-刷题日结
  17. uniapp 跳转公众号获其他小程序
  18. 易语言突破百度云防护
  19. Parameter 0 of method selGoods in com.jm.provider.service.admin.GoodsServerImpl required a bean of t
  20. LaTeX in 24 Hours - 3. Formatting Texts I

热门文章

  1. Java技术--maven的assembly插件打包(依赖包归档)
  2. 族谱 php,族谱 - 百家姓 - 族谱录
  3. sql server和mysql 分页_基于Sql server数据库的四种分页方式总结
  4. 论“面向对象”之下的爱情观
  5. 计算机与书法专业,厉害了!计算机应用专业的他获省级书法比赛一等奖
  6. 外网访问Openwrt路由器管理Web及SSH
  7. Flash 系列:Nor/Nand/OneNand
  8. android媒体播放器课程设计,基于Android的多媒体播放器课程设计报告
  9. 使用Tkinter + urllib + requests 实现自动下载百度图片
  10. 【PYthon分布式】huey:python轻量级异步任务队列简介