SpringBoot中使用Quartz管理定时任务的方法

定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 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、创建数据表

数据模型:

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

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

列表页:

新增页:

四、定时任务

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;

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

总结

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

(0)

相关推荐

  • 浅谈SpringBoot集成Quartz动态定时任务

    SpringBoot自带schedule 沿用的springboot少xml配置的优良传统,本身支持表达式等多种定时任务 注意在程序启动的时候加上@EnableScheduling @Scheduled(cron="0/5 * * * * ?") public void job(){ System.out.println("每五秒执行一次"); } 为什么要使用Quartz 多任务情况下,quartz更容易管理,可以实现动态配置 执行时间表达式: 表达式示例: 集成

  • SpringBoot与Quartz集成实现分布式定时任务集群的代码实例

    Spring Boot与Quartz集成实现分布式定时任务集群 直接贴代码 POM <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs

  • springboot整合quartz实现定时任务示例

    在做项目时有时候会有定时器任务的功能,比如某某时间应该做什么,多少秒应该怎么样之类的. spring支持多种定时任务的实现.我们来介绍下使用spring的定时器和使用quartz定时器 1.我们使用spring-boot作为基础框架,其理念为零配置文件,所有的配置都是基于注解和暴露bean的方式. 2.使用spring的定时器: spring自带支持定时器的任务实现.其可通过简单配置来使用到简单的定时任务. @Component @Configurable @EnableScheduling p

  • SpringBoot定时任务两种(Spring Schedule 与 Quartz 整合 )实现方法

    前言 最近在项目中使用到定时任务,之前一直都是使用Quartz 来实现,最近看Spring 基础发现其实Spring 提供 Spring Schedule 可以帮助我们实现简单的定时任务功能. 下面说一下两种方式在Spring Boot 项目中的使用. Spring Schedule 实现定时任务 Spring Schedule 实现定时任务有两种方式 1. 使用XML配置定时任务, 2. 使用 @Scheduled 注解. 因为是Spring Boot 项目 可能尽量避免使用XML配置的形式,

  • Springboot整个Quartz实现动态定时任务的示例代码

    简介 Quartz是一款功能强大的任务调度器,可以实现较为复杂的调度功能,如每月一号执行.每天凌晨执行.每周五执行等等,还支持分布式调度.本文使用Springboot+Mybatis+Quartz实现对定时任务的增.删.改.查.启用.停用等功能.并把定时任务持久化到数据库以及支持集群. Quartz的3个基本要素 Scheduler:调度器.所有的调度都是由它控制. Trigger: 触发器.决定什么时候来执行任务. JobDetail & Job: JobDetail定义的是任务数据,而真正的

  • springboot整合Quartz实现动态配置定时任务的方法

    前言 在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置,下面就通过一个简单的示例,来实现这个功能. 一.新建一个springboot工程,并添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency

  • SpringBoot中使用Quartz管理定时任务的方法

    定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 Token 信息等等,之前我们都是在项目中规定这个定时任务什么时候启动,到时间了便会自己启动,那么我们想要停止这个定时任务的时候,就需要去改动代码,还得启停服务器,这是非常不友好的事情 直至遇见 Quartz,利用图形界面可视化管理定时任务,使得我们对定时任务的管理更加方便,快捷 一.Quartz 简介 Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中.它提供了巨大的灵

  • springBoot项目集成quartz开发定时任务案例及注意事项

    目录 quartz下载.安装 实战案例 常见问题及解决方案 quartz下载.安装 Quartz是完全由java开发的一个开源的任务日程管理系统,任务进度管理器就是一个在预先确定的时间到达时,负责执行(或者通知)一段程序或功能的系统,即定时执行某个任务.Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能.这些功能的主要接口(API)是Scheduler接口.它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度. 上图是q

  • SpringBoot中定制异常页面的实现方法

    定制异常页面,可以避免用户产生恐慌心理,使得产品有更好的用户体验.今天来学习在 SpringBoot 中如何定制开发异常页面 一.历史回顾 在 SpringMVC 年代,我们的异常页面一般配置在 web.xml 文件中,如下: <!-- 配置404页面 --> <error-page> <error-code>404</error-code> <location>/error/404.html</location> </erro

  • SpringBoot中使用Swagger的超简单方法

    Swagger号称世界上最流行的Api框架,它是RestFul 风格的Api.文档在线自动生成工具:Api文档与API定义同步更新.可以直接运行,能在线测试API接口:支持多种编程语言:(Java.PHP等). 官网:https://swagger.io/ springBoot使用swagger太麻烦,每次都需要编写config?如果我告诉你有这么一种方式,你只需要配置yml文件,你学还是不学? 整合Swagger 依赖: <!-- Swagger --> <dependency>

  • SpringBoot中使用Servlet三大组件的方法(Servlet、Filter、Listener)

    本篇主要讲解SpringBoot当中使用Servlet三大组件,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧! 三大组件作用 1.Servlet Servlet是用来处理客户端请求的动态资源,也就是当我们在浏览器中键入一个地址回车跳转后,请求就会被发送到对应的Servlet上进行处理. Servlet的任务有: 1.接收请求数据:我们都知道客户端请求会被封装成HttpServletRequest对象,里面包含了请求头.参数等各种信息. 2.处理请求:通常我

  • SpringBoot中时间格式化的五种方法汇总

    目录 前言 时间问题演示 1.前端时间格式化 JS 版时间格式化 2.SimpleDateFormat格式化 3.DateTimeFormatter格式化 4.全局时间格式化 实现原理分析 5.部分时间格式化 总结 参考 & 鸣谢 前言 在我们日常工作中,时间格式化是一件经常遇到的事儿,所以本文我们就来盘点一下 Spring Boot 中时间格式化的几种方法. 时间问题演示 为了方便演示,我写了一个简单 Spring Boot 项目,其中数据库中包含了一张 userinfo 表,它的组成结构和数

  • Python中schedule模块关于定时任务使用方法

    目录 1 取消定时任务 2 定时任务只执行一次 3 获取所有的定时任务 4 取消所有任务 5 给定时任务打标签,同样通过标签获取或取消定时任务 1 取消定时任务 比如当满足一定条件时,就取消定时任务,在这种场景下,不可能说把进程干掉,所以可以利用取消定时任务的功能 如下代码,通过count控制当执行了5此以后,就取消定时任务 import schedule import time count=0 def do_func(name,age): global count count+=1 print

  • springboot中nacos-client获取配置的实现方法

    目录 1.导入nacos的maven包 2.nacos-config-spring-boot-autoconfigure解析 3.NacosConfigEnvironmentProcessor逻辑解析 在springboot中使用nacos的小伙伴是不是跟我有一样的好奇,springboot中nacos-client是怎么获取配置的?今天我跟了一下代码,大致的流程弄懂了,分享给大家. 1.导入nacos的maven包 <dependency> <groupId>com.alibab

  • SpringBoot集成Quartz实现定时任务的方法

    1 需求 在我的前后端分离的实验室管理项目中,有一个功能是学生状态统计.我的设计是按天统计每种状态的比例.为了便于计算,在每天0点,系统需要将学生的状态重置,并插入一条数据作为一天的开始状态.另外,考虑到学生的请假需求,请假的申请往往是提前做好,等系统时间走到实际请假时间的时候,系统要将学生的状态修改为请假. 显然,这两个子需求都可以通过定时任务实现.在网上略做搜索以后,我选择了比较流行的定时任务框架Quartz. 2 Quartz Quartz是一个定时任务框架,其他介绍网上也很详尽.这里要介

  • 在SpringBoot中使用Logback管理记录日志

    SpringBoot的默认日志配置 SpringBoot 开箱即用,默认帮你配置了日志框架,使用 Commons Logging ,但是默认配置也提供了对常用日志的支持,如: Java Util Logging , Log4J , Log4J2 和 Logback.每种Logger都可以通过配置使用控制台或者文件输出日志内容. 控制台输出 关于log日志,首先说说的5个日志级别 LEVEL: 从高到低分别是 ERROR . WARN . INFO . DEBUG . TRACE 低级别的会输出高

随机推荐