Quartz整合到SpringBoot(持久化到数据库)

背景

最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于扩展和调控,就想到了用Quartz实现。

Quartz简介

Quartz是一个优秀的任务调度框架,有静态任务调度和动态任务调度两种类型。静态任务调度是编写好代码,然后在启动的时候,将任务保存在内内存中,也就是下面的RAMJobStore,实现相对简单;动态任务调度主要是持久化到数据库,即下面的JDBC作业存储,实现方式相对复杂一点,但是可操作性更强。

  • RAMJobStore :RAM也就是内存,默认情况下Quartz会将任务调度存在内存中,这种方式性能是最好的,因为内存的速度是最快的。不好的地方就是数据缺乏持久性,但程序崩溃或者重新发布的时候,所有运行信息都会丢失
  • JDBC作业存储:存到数据库之后,可以做单点也可以做集群,当任务多了之后,可以统一进行管理。关闭或者重启服务器,运行的信息都不会丢失。缺点就是运行速度快慢取决于连接数据库的快慢。

Quartz相关概念

  • Scheduler:调度器,进行任务调度;quartz的大脑

  • Job:业务job,亦可称业务组件;定时任务的具体执行业务需要实现此接口,调度器会调用此接口的execute方法完成我们的定时业务

  • JobDetail:用来定义业务Job的实例,我们可以称之为quartz job,很多时候我们谈到的job指的是JobDetail

  • Trigger:触发器,用来定义一个指定的Job何时被执行

  • JobBuilder:Job构建器,用来定义或创建JobDetail的实例;JobDetail限定了只能是Job的实例

  • TriggerBuilder:触发器构建器,用来定义或创建触发器的实例

RAMJobStore的实现

整体流程

  • 首先需要创建任务(Job),比如取消订单、定时发送短信邮件之类的,这是我们的任务主体,也是写业务逻辑的地方。

  • 创建任务调度器(Scheduler),这是用来调度任务的,主要用于启动、停止、暂停、恢复等操作,也就是那几个api的用法。

  • 创建任务明细(JobDetail),最开始我们编写好任务(Job)后,只是写好业务代码,并没有触发,这里需要用JobDetail来和之前创建的任务(Job)关联起来,便于执行。

  • 创建触发器(Trigger),触发器是来定义任务的规则的,比如几点执行,几点结束,几分钟执行一次等等。这里触发器主要有两大类(SimpleTrigger和CronTrigger)。

  • 根据Scheduler来启动JobDetail与Trigger

导入依赖

<!--quartz定时调度依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

创建Job

要求: 需实现Job接口,并且这个接口就一个execute()方法需要重写,方法内容就是具体的业务逻辑。如果是动态任务呢,比如取消订单,每次执行都是不同的订单号。这个时候就需要在创建任务(JobDetail)或者创建触发器(Trigger)的那里传入参数,然后在这里通过JobExecutionContext来获取参数进行处理,

/*** @author Mr.zhou* @version 1.0* @date 2020/11/17 17:52*/
public class TestJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.err.println("Hello quartz, " + jobExecutionContext.getJobDetail().getJobDataMap().getString("message"));System.err.println("Hello quartz, " + jobExecutionContext.getMergedJobDataMap().getString("work"));System.err.println();}
}

创建任务调度器

这里我们用的是SpringBoot,SpringBoot会自动帮我们装配任务调度器,在使用的时候,直接注入即可。

@Resource
private Scheduler scheduler;

如果没用使用SpringBoot,那么就需要手动创建了。通常优秀的框架,创建某些核心类都会使用工厂模式或者构建者模式,值得学习。

SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();

创建任务明细:JobDetail

// 创建任务详情
JobDetail jobDetail = JobBuilder.newJob(TestJob.class)// 添加参数.usingJobData("message", "米西米西滑不拉几")// 添加认证信息,共有三种认证方式.withIdentity(orderNum).build();

创建触发器:Trigger

SimpleSchedule策略

// 创建触发器
Trigger trigger = TriggerBuilder.newTrigger()// 添加参数.usingJobData("work", "我在写代码,你呢?")// 认证信息.withIdentity(orderNum)// 开始时间.startAt(start)// 执行策率,有SimpleSchedule和CronSchedule两种.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();

CronSchedule策略

// 创建触发器
Trigger trigger = TriggerBuilder.newTrigger()// 添加参数.usingJobData("work", "我在写代码,你呢?")// 认证信息.withIdentity(orderNum)// 开始时间.startNow()// 执行策率,有SimpleSchedule和CronSchedule两种.withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * *")).build();

注意:.startNow().startAt()这里有个坑,这两个方法是对同一个成员变量进行修改的 也就是说startAt和startNow同时调用的时候任务开始的时间是按后面调用的方法为主的,谁写在后面用谁。看看这里的源码:

启动任务

上面都已经将工作完成了,接下来就是启动任务了

// 启动定时任务
scheduler.scheduleJob(jobDetail, trigger);
if (!scheduler.isShutdown()) {scheduler.start();
}

实现任务的常规操作

上面已经介绍了怎么去定义一个任务,并成功启动,下面就简单介绍任务的启动、暂停、恢复、以及删除等操作。

@RestController
@RequestMapping("/quartz")
public class QuartzController {@Resourceprivate Scheduler scheduler;/*** 启动一个定时任务* @param orderNum 编号* @return 结果* @throws SchedulerException 异常*/@PostMapping("/start")public R quartz(@RequestParam("orderNum") String orderNum) throws SchedulerException {// 当前时间10秒之后Date start = new Date(System.currentTimeMillis() + 10 * 1000);// 创建任务详情JobDetail jobDetail = JobBuilder.newJob(TestJob.class)// 添加参数.usingJobData("message", "米西米西滑不拉几")// 添加认证信息,共有三种认证方式.withIdentity(orderNum).build();// 创建触发器Trigger trigger = TriggerBuilder.newTrigger()// 添加参数.usingJobData("work", "我在写代码,你呢?")// 认证信息.withIdentity(orderNum)// 开始时间.startAt(start)// 执行策率,有SimpleSchedule和CronSchedule两种.withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?")).build();// 启动定时任务scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start();}System.err.println("定时任务启动成功");return R.ok();}/*** 任务关闭* @param oderNum 标识* @return 结果* @throws SchedulerException 异常*/@PostMapping("/shutdown")public R shutdown(@RequestParam("orderNum") String oderNum) throws SchedulerException {scheduler.pauseTrigger(TriggerKey.triggerKey(oderNum));return R.ok();}/*** 任务恢复* @param oderNum 标识* @return 结果* @throws SchedulerException 异常*/@PostMapping("/resume")public R resume(@RequestParam("orderNum") String oderNum) throws SchedulerException {scheduler.resumeTrigger(TriggerKey.triggerKey(oderNum));return R.ok();}/*** 任务删除* @param oderNum 标识* @return 结果* @throws SchedulerException 异常*/@PostMapping("/del")public R del(@RequestParam("/oderNum") String oderNum) throws SchedulerException {scheduler.pauseTrigger(TriggerKey.triggerKey(oderNum));scheduler.unscheduleJob(TriggerKey.triggerKey(oderNum));scheduler.deleteJob(JobKey.jobKey(oderNum));return R.ok();}}

结果示例

由于我项目已经集成了Swagger文档,所以我就直接在这上面进行接口测试了

  • 开启任务

  • 任务启动之后的输出效果

到这里,应该就清楚了Quartz和SpringBoot整合,大致流程,了解了RAMJobStore如何实现,那么数据库持久化的实现也应该有了基本思路了。

JDBC作业存储实现

大致流程

  • 创建SpringBoot工程,并且加入Web和Quartz依赖
  • 下载Quartz官方提供的数据库脚本,注意版本,并将其导入到自己项目的数据库中
  • 添加Quartz配置

SpringBoot中实现quartz定时任务相关推荐

  1. java quartz管理,SpringBoot中使用Quartz管理定时任务的方法

    定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 Token 信息等等,之前我们都是在项目中规定这个定时任务什么时候启动,到时间了便会自己启动,那么我们想要停止这个定时任 ...

  2. SpringBoot中整合Quartz

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

  3. SpringBoot中的Quartz应用

    Spring自带定时器任务: code: import org.springframework.beans.factory.annotation.Configurable; import org.sp ...

  4. springBoot下使用quartz定时任务;动态修改任务执行时间

    先上依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spri ...

  5. Spring框架中的Quartz定时任务使用笔记(通过@Scheduled注解的方式实现)

    1.修改spring的xml配置信息 applicationContext.xml 三个部分内容 1.xmlns添加:xmlns:task="http://www.springframewo ...

  6. springboot中如何创建定时任务,以及corn表达式规则

    首先,需要在主启动类上添加@EnableScheduling注解,开启定时任务相关配置. @SpringBootApplication @EnableScheduling public class A ...

  7. springmvc中实现quartz定时任务

    1.maven项目添加如下两个jar包,当然也需要相应的spring 的Jar <!-- Spring Quartz定时器 begin --><dependency><g ...

  8. hutool的定时任务不支持依赖注入怎么办_可调度定时任务在SpringBoot中的实践

    定时任务在我们的项目中或多或少都会使用到,不论你是初级程序员,还是有多年工作经验的中高级程序员,在项目中加一个定时任务去处理业务的一个aspect,为什么用了一个英文单词'aspect'?而不是'切面 ...

  9. Springboot 使用quartz 定时任务 增删改查

    前段时间公司项目用到了 定时任务 所以写了一篇定时任务的文章 ,浏览量还不错 , Springboot 整合定时任务 ) 所以就准备写第二篇, 如果你是一名Java工程师,你也可以会看到如下的页面 , ...

最新文章

  1. MySQL:一个死锁分析 (未分析出来的死锁)
  2. 皮一皮:一顿操作猛如虎...
  3. C++你不知道的那些事儿—C++语言的15个晦涩特性
  4. Jquery跳出each循环
  5. 从《爱莉克斯》说起,聊聊当前 VR 游戏设计的“困境”与“尝试”
  6. 【SAM】差异(P4248)
  7. 蚂蚁金服OceanBase挑战TPCC丨TPC-C基准测试之链路层优化
  8. 使用bat向文件的第一行中写入内容
  9. sql 执行 delete 的时候,结合子查询 exists ,怎样支持别名呢?
  10. ofo现在还有退路吗?
  11. 龙芯 python_在UOS20-龙芯(MIPS64EL)上安装 opencv-python
  12. android换肤的实现方案,Android换肤技术总结
  13. pdf 转化为jpg python 批量转化
  14. 自定义原生JS键盘快捷键和vue-hotkey
  15. 【Linux_02】
  16. Leco题目:整数反转
  17. AEJoy —— 详解 AE 如何将 png 序列帧导出为 SVGA 动画文件
  18. 项目型销售之定义与特点简介
  19. 刷机大师乐蛙定制版 v3.4.0 官方版
  20. linuxMint在虚拟机下装VMware Tolls

热门文章

  1. 2022-2028年中国BOPP消光膜行业全景调研及竞争格局预测报告
  2. python 通过双栈实现队列
  3. 2018-10:自考总结
  4. 利用MONAI加速医学影像学的深度学习研究
  5. 使用现场总线更快更远
  6. React router 的 Route 中 component 和 render 属性理解
  7. java gui 案例_JavaGui入门—布局的嵌套使用附实例
  8. C++实现九九乘法表
  9. python >> 和 <<
  10. Android ndk 安装教程 以及环境变量配置