当前位置: 首页 > news >正文

Spring boot整合quartz方法

目录

1.定时任务

1.quartz说明

2.Quartz提供了不同的数据存储策略以管理作业调度信息:

1.Quartz引入依赖

2.开发定时任务

(1)更新定时任务

(2)停止定时任务

(3)唤醒定时任务

(4)删除定时任务


1.定时任务

定时任务的实现途径多种多样,以下是一些不同的方法:

1. 在应用程序的启动类中引入`@EnableScheduling`注解,以此激活定时任务的功能。随后,可以利用注解`@Scheduled`,配合Cron表达式(例如`@Scheduled(cron = "0/1 * * * * ")`)来定义任务的执行频率,同时确保这些任务被注册为Spring管理的Bean。

2. 采用外部任务调度框架,例如xxl-job或elastic-Job,这些框架提供了额外的功能和灵活性,以满足更复杂的调度需求。

3. 使用Quartz作为底层实现,许多第三方框架实际上都是基于Quartz构建的,它们提供了更高级的调度功能和更好的集成支持。

1.quartz说明

Quartz是一个纯Java编写的工作调度框架,它包含以下核心组件:

1. 调度器(Scheduler): ? ?这是Quartz中负责调度作业的核心组件。它通过与触发器(Trigger)和作业详情(JobDetail)的交互来控制作业的执行。调度器作为一个容器,保存了作业和触发器,它们在调度器中都有唯一的组和名称,这些标识符用于调度器内部查找和识别特定的作业或触发器。触发器和作业详情的组名和名称必须是唯一的,尽管它们可以相同,因为它们属于不同的类别。

2. 触发器(Trigger): ? ?在Quartz中,触发器定义了作业执行的时间规则。它有两个主要的子类型:SimpleTrigger和CronTrigger,分别用于简单的周期性调度和复杂的时间表调度。

3. 作业详情(JobDetail): ? ?这包含了Quartz中作业的具体信息,包括作业的唯一标识和要执行的任务。作业详情还允许通过JobDataMap传递额外的数据给作业。

4. 作业(Job): ? ?这是Quartz中定义作业具体执行逻辑的接口。实现这个接口的类包含了作业执行的核心代码。

5. 作业构建器(JobBuilder): ? ?这是一个工具类,用于构建作业实例,并定义作业的属性,如名称和组名。构建的实例将代表一个实际要执行的作业。

6. 触发器构建器(TriggerBuilder): ? ?这个工具类用于创建触发器实例,定义触发器的属性和行为。

7. 监听器(Listener): ? ?Quartz提供了多种监听器,包括作业监听器(JobListener)、触发器监听器(TriggerListener)和调度器监听器(SchedulerListener),它们用于监控作业、触发器和调度器的事件和状态变化。

2.Quartz提供了不同的数据存储策略以管理作业调度信息:

内存存储(RAMJobStore): Quartz默认使用内存作为存储介质,这种方式因其直接在内存中操作而具有极高的性能。然而,这种存储方式不具备数据持久性,一旦应用程序崩溃或需要重新部署,所有存储的调度信息将无法保留。

数据库存储: 通过将调度信息存储在数据库中,Quartz可以实现单实例或集群部署,便于对大量作业进行集中管理和动态控制,如暂停、停止或修改作业。即使在服务器关闭或重启后,作业的调度信息也能得以保留。不过,这种存储方式的性能会受到数据库连接速度的影响。

1.Quartz引入依赖

首先,要在Springboot项目可以直接引入下面依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>

如果是非Springboot项目,可以引入以下依赖

<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.3</version>
</dependency>

2.开发定时任务

首先,我们需要创建一个类

package com.example.yin.taskjob;import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;public class TaskJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.out.println("定时任务执行:"+System.currentTimeMillis());}
}

接着,我们需要为他设置接口。

public interface QuartzService {public R addCronJob(String jobName, String cron, String jobClassName, String triggerName);public R updateCronJob(String jobName,String cron, String jobClassName);public R pauseCronJob(String jobName, String triggerName);public R resumeCronJob(String jobName, String triggerName);public R deleteCronJob(String jobName, String jobGroup, String triggerName, String triggerGroup);
}

接口中的方法用于添加、更新、暂停、恢复和删除基于Cron表达式的定时作业;返回类型为R的对象,R可能是一个自定义的响应类,用于封装方法执行的结果,请根据自己项目来修改!

然后,定时任务继承TaskJob,并实现其方法

@Service
public class QuartServiceImpl implements QuartzService {@Autowiredprivate Scheduler scheduler;private static final String DEFAULT_JOB_GROUP = "default_job_group";private static final String DEFAULT_TRIGGER_GROUP = "default_trigger_group";private static final String TRIGGER_PRE = "Trigger_";@Overridepublic R addCronJob(String jobName, String cron, String jobClassName, String triggerName) {try{JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);if (scheduler.checkExists(jobKey)){return R.fail("【添加定时任务】该作业已存在");}//构建jobJobDetail job = (JobDetail) JobBuilder.newJob((Class<? extends Job>) Class.forName(jobClassName)).withIdentity(jobKey).build();//Cron表达式定时构造器CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(cron);//构建TriggerTrigger trigger = TriggerBuilder.newTrigger().withIdentity(TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP)).withSchedule(cronSchedule).build();//启动调度scheduler.scheduleJob(job, trigger);scheduler.start();}catch (Exception e){return R.fail("创建定任务失败,原因是:" + e.getMessage());}return  R.success("创建定时任务成功!", jobName + ",任务表达式:" + cron);}

这个方法提供了一个完整的流程,用于将一个新的Cron作业添加到Quartz调度器中,并确保作业按照指定的Cron表达式执行。通过动态加载作业类和构建触发器,这个方法提供了灵活的作业调度能力。

然后,让我们创建一个控制类

@RestController
@RequestMapping("/quartz")
public class QuartzController {@Autowiredprivate QuartzService quartzService;@PostMapping("createJob")public R createJob(@RequestBody JobInfo jobInfo) {return quartzService.addCronJob(jobInfo.getJobName(),jobInfo.getCron(),jobInfo.getJobClassName(), jobInfo.getTriggerName());}

到这里,其实一个简单的Quartz定时任务已经完成了

我们可以去swagger-ui测试效果(不会使用swagger-ui的小伙伴,可以使用其他接口软件)

测试接口推荐

这里推荐几个接口地址,供小伙伴自行选择

1.Apifox - API 文档、调试、Mock、测试一体化协作平台。拥有接口文档管理、接口调试、Mock、自动化测试等功能,接口开发、测试、联调效率,提升 10 倍。最好用的接口文档管理工具,接口自动化测试工具。[这里是图片001]https://apifox.com/2.Postman: The World’s Leading API Platform | Sign Up for Free。支持各种 HTTP 请求方法,并且提供了强大的测试脚本功能,你可以为每个请求编写测试用例,自动化你的 API 测试过程。(建议科学上网使用)

3.The Collaborative API Development Platform - Insomnia。是一个轻量级的 REST 客户端,界面干净利落,使用起来非常直观,虽然 Insomnia 主要聚焦在 API 测试上,但它也提供了基本的文档生成功能。

spring boot项目控制台会显示此效果

最后,我们可以在实现方法中添加更新定时任务,停止定时任务,唤醒定时任务,删除定时任务

(1)更新定时任务
@Overridepublic R updateCronJob(String jobName, String cron, String triggerName) {try{TriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP);CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(cron);CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronSchedule).build();scheduler.rescheduleJob(triggerKey, trigger);return R.success("更新定时任务成功!");}catch (Exception e){return R.fail("更新定时任务失败,原因为:" + e.getMessage());}}
(2)停止定时任务
@Overridepublic R pauseCronJob(String jobName, String triggerName) {try {TriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP);JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);// 检查作业和触发器是否存在if (!scheduler.checkExists(jobKey) || !scheduler.checkExists(triggerKey)) {return R.fail("作业或触发器不存在");}// 暂停触发器scheduler.pauseTrigger(triggerKey);return R.success("暂停定时任务成功!");} catch (Exception e) {return R.fail("暂停定时任务失败,原因是:" + e.getMessage());}}
(3)唤醒定时任务
 @Overridepublic R resumeCronJob(String jobName, String triggerName) {try {// 构建触发器keyTriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP);// 恢复触发器scheduler.resumeTrigger(triggerKey);return R.success("恢复定时任务成功!");} catch (Exception e) {return R.fail("恢复定时任务失败,原因是:" + e.getMessage());}}
(4)删除定时任务
@Overridepublic R deleteCronJob(String jobName, String jobGroup, String triggerName, String triggerGroup) {try {JobKey jobKey = JobKey.jobKey(jobName,  DEFAULT_JOB_GROUP);TriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP);if (!scheduler.checkExists(jobKey) ||!scheduler.checkExists(triggerKey)) {return R.fail("【删除定时任务】作业或触发器不存在");}scheduler.unscheduleJob(triggerKey);scheduler.deleteJob(jobKey);return R.success("删除定时任务成功!", jobName);} catch (Exception e) {return R.fail("删除定时任务失败,原因为:" + e.getMessage());}}

在添加完所有方法后,将相应的控制类补全,swagger-ui就会呈现所有接口

以下是剩余控制类方法

@PostMapping("updateJob")public R updateJob(@RequestBody JobInfo jobInfo) {return quartzService.updateCronJob(jobInfo.getJobName(), jobInfo.getCron(), jobInfo.getTriggerName());}@PostMapping("pauseJob")public R pauseJob(@RequestBody JobInfo jobInfo) {return quartzService.pauseCronJob(jobInfo.getJobName(), jobInfo.getTriggerName());}@PostMapping("resumeJob")public R resumeJob(@RequestBody JobInfo jobInfo) {return quartzService.resumeCronJob(jobInfo.getJobName(), jobInfo.getTriggerName());}@DeleteMapping("deleteJob")public R deleteJob(@RequestBody JobInfo jobInfo) {return quartzService.deleteCronJob(jobInfo.getJobName(), jobInfo.getJobGroup(), jobInfo.getTriggerName(), jobInfo.getTriggerGroup());}
}

我们可以到swagger-ui去查看接口是否齐全

可以看到,我们的实现接口是正确显示的,到这里,Spring boot整合Quartz项目就算完成了。

相关文章:

Spring boot整合quartz方法

目录 1.定时任务 1.quartz说明 2.Quartz提供了不同的数据存储策略以管理作业调度信息&#xff1a; 1.Quartz引入依赖 2.开发定时任务 &#xff08;1&#xff09;更新定时任务 &#xff08;2&#xff09;停止定时任务 &#xff08;3&#xff09;唤醒定时任务 &#xff…...

网站改HTTPS方法

默认的网站建设好后打开的样子那看起来像是钓鱼网站&#xff0c;现在的浏览器特别只能&#xff0c;就是你新买来的电脑默认的浏览器同样也会出现这样“不安全”提示。 传输协议启动了向全球用户安全传输网页内容的流程。然而&#xff0c;随着HTTPS的推出&#xff0c;传输协议通…...

数据中台是什么?:架构演进、业务整合、方向演进

文章目录 1. 引言2. 数据中台的概念与沿革2.1 概念定义2.2 历史沿革 3. 数据中台的架构组成与关键技术要素解析3.1 架构组成3.2 关键技术要素 4. 数据中台与其他平台的对比详细解析 5. 综合案例&#xff1a;金融行业数据中台落地实践5.1 背景5.2 解决方案5.3 成果与价值 6. 方向…...

Java Stream API:高效数据处理的利器引言

Java Stream API&#xff1a;高效数据处理的利器引言 在 Java 编程中&#xff0c;数据处理是一项极为常见且关键的任务。传统的 for 循环在处理数据集合时&#xff0c;往往会导致代码变得冗长、复杂&#xff0c;这不仅增加了代码的编写难度&#xff0c;还降低了代码的可读性和…...

qml之Text 组件显示当前时间

在 QML 中,显示时间的常用组件是 Text,结合 JavaScript 时间函数或者 Qt 的时间模块来实现动态时间显示。虽然 QML 没有专门用于显示时间的组件,但可以通过 Text 来显示格式化后的时间信息。 1. 使用 Text 组件显示当前时间 示例代码: import QtQuick 2.15 import QtQui…...

两栏布局、三栏布局、水平垂直居中

文章目录 1 两栏布局1.1 浮动 margin1.2 浮动 BFC1.3 flex布局1.4 左绝父相 margin1.5 右绝父相 方向定位 2 三栏布局2.1 子绝父相 margin2.2 flex布局2.3 浮动 margin2.4 圣杯布局2.5 双飞翼布局 3 水平垂直居中3.1 绝对定位 translate3.2 绝对定位 margin3.3 绝对定位…...

Hanoi ( 2022 ICPC Southeastern Europe Regional Contest )

Hanoi &#xff08; 2022 ICPC Southeastern Europe Regional Contest &#xff09; The original problem “Towers of Hanoi” is about moving n n n circular disks of distinct sizes between 3 3 3 rods. In one move, the player can move only the top disk from on…...

Matplotlib基础01( 基本绘图函数/多图布局/图形嵌套/绘图属性)

Matplotlib基础 Matplotlib是一个用于绘制静态、动态和交互式图表的Python库&#xff0c;广泛应用于数据可视化领域。它是Python中最常用的绘图库之一&#xff0c;提供了多种功能&#xff0c;可以生成高质量的图表。 Matplotlib是数据分析、机器学习等领域数据可视化的重要工…...

SMU寒假训练第二周周报

训练情况 本周是第二周&#xff0c;训练情况比第一周好一点点&#xff0c;也仅仅是好一点点&#xff0c;经过春节以及后遗症&#xff0c;牛客更是打的稀烂&#xff0c;还不如去年&#xff0c;都不知道自己在干嘛&#xff0c;训练赛情况也非常糟糕&#xff0c;还要去搞社会实践…...

解锁全新视界:一键畅享 360 度全景图与多格式转换

软件介绍 各位朋友&#xff0c;大家好&#xff01;今天要给大家引荐一款超实用的全景图转换“神器”——Pano2VR Pro 的最新版本。在当今这个追求极致视觉体验的时代&#xff0c;它宛如一把神奇的钥匙&#xff0c;能够解锁全新的视觉领域&#xff0c;将平平无奇的不同角度图像…...

python:面向对象案例烤鸡翅

自助烤鸡翅的需求&#xff1a; 1.烤鸡翅的时间和对应的状态&#xff1a; 0-4min :生的 4-7min:半生不熟 7-12min&#xff1a;熟了 12min以上&#xff1a;烤糊了 2.添加调料&#xff1a; 客户根据自己的需求添加 定义烤鸡翅的类、属性和方法&#xff0c;显示对象的信息 …...

游戏外挂原理解析:逆向分析与DLL注入实战(植物大战僵尸

目录 1.前言2.外挂类型3.前置知识4.CE查找基质4.1 逐步分析4.2 暴力搜索5.实现数值外挂6.dll导入表注入7.实现行为外挂(无敌类型)8.源码下载与外挂进阶本篇原文为:游戏外挂原理解析:逆向分析与DLL注入实战(植物大战僵尸)。 更多C++进阶、rust、python、逆向等等教程,可…...

【10.10】队列-设计自助结算系统

一、题目 请设计一个自助结账系统&#xff0c;该系统需要通过一个队列来模拟顾客通过购物车的结算过程&#xff0c;需要实现的功能有&#xff1a; get_max()&#xff1a;获取结算商品中的最高价格&#xff0c;如果队列为空&#xff0c;则返回 -1add(value)&#xff1a;将价格为…...

android的ViewModel和LiveData 简介

ViewModel ViewModel 的优势 ViewModel 的替代方案是保存要在界面中显示的数据的普通类。在 activity 或 Navigation 目的地之间导航时&#xff0c;这可能会造成问题。此时&#xff0c;如果您不利用保存实例状态机制存储相应数据&#xff0c;系统便会销毁相应数据。ViewModel…...

Linux系统之free命令的基本使用

Linux系统之free命令的基本使用 一、free命令介绍二、free命令的使用帮助2.1 free命令的帮助信息2.2 free命令帮助解释 三、free命令的基本使用3.1 显示内存使用情况3.2 新增总计条目3.3 显示内存详细信息 四、注意事项 一、free命令介绍 free 命令是 Linux 系统中用于显示系统…...

大模型赋能网络安全整体应用流程概述

一、四个阶段概述 安全大模型的应用大致可以分为四个阶段: 阶段一主要基于开源基础模型训练安全垂直领域的模型; 阶段二主要基于阶段一训练出来的安全大模型开展推理优化、蒸馏等工序,从而打造出不同安全场景的专家模型,比如数据安全领域、安全运营领域、调用邮件识别领…...

SpringCloud - Nacos注册/配置中心

前言 该博客为Nacos学习笔记&#xff0c;主要目的是为了帮助后期快速复习使用 学习视频&#xff1a;7小快速通关SpringCloud 辅助文档&#xff1a;SpringCloud快速通关 一、简介 Nacos官网&#xff1a;https://nacos.io/docs/next/quickstart/quick-start/ Nacos /nɑ:kəʊ…...

面试准备——Java理论高级【笔试,面试的核心重点】

集合框架 Java集合框架是面试中的重中之重&#xff0c;尤其是对List、Set、Map的实现类及其底层原理的考察。 1. List ArrayList&#xff1a; 底层是动态数组&#xff0c;支持随机访问&#xff08;通过索引&#xff09;&#xff0c;时间复杂度为O(1)。插入和删除元素时&#…...

AI伴读-清华大学104页《DeepSeek:从入门到精通》

辅助工具&#xff1a;deepseek、豆包AI伴读 官网&#xff1a;DeepSeekDeepSeek, unravel the mystery of AGI with curiosity. Answer the essential question with long-termism.https://www.deepseek.com/https://www.deepseek.com/清华大学104页《DeepSeek&#xff1a;从入…...

unity学习34:角色相关3,触发器trigger,铰链 hingejoint 等 spring joint, fixed joint

目录 1 触发的实现条件 1.1 碰撞的的实现条件 1.2 触发的实现条件 1.3 触发器trigger&#xff0c;直接拿 碰撞器collider修改下配置即可 2 触发器相关实验&#xff1a;触发开门效果 2.0 目标 2.1 player物体的属性 2.2 新建一个trigger 物体 2.3 新建一个被trigger 控…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...