Spring Quartz项目实现Job的动态控制

news/2024/4/20 4:30:28/文章来源:https://blog.csdn.net/qq_40579464/article/details/129708457

一、简单介绍

Quartz可以对job进行简单控制,但不支持分布式,也没有管理界面和任务分片,但使用起来比较简易。


二、创建简单Demo

我们开始简单使用一下,首先创建Demo,在pom文件中加入以下依赖。

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version><relativePath />
</parent><dependencies><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><!--hutool工具包--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.6</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.6.3</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>2.5.6</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.19</version></dependency>
</dependencies>

application.yml如下。

server:port: 8090
#  servlet:
#    context-path: /logging:level:root: infospring:datasource:url: jdbc:mysql://127.0.0.1:3306/quartz?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&useSSL=false&allowMultiQueries=trueusername: rootpassword: 123456
#    driver-class-name: com.mysql.jdbc.Driver# 时间格式jackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ssquartz:job-store-type: jdbcinitialize-schema: embedded#设置自动启动,默认为 trueauto-startup: true#启动时更新己存在的Joboverwrite-existing-jobs: trueproperties:org:quartz:scheduler:instanceName: MySchedulerinstanceId: AUTOjobStore:class: org.quartz.impl.jdbcjobstore.JobStoreTXdriverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegatetablePrefix: QRTZ_isClustered: truemisfireThreshold: 60000clusterCheckinInterval: 10000threadPool:class: org.quartz.simpl.SimpleThreadPoolthreadCount: 50threadPriority: 5threadsInheritContextClassLoaderOfInitializingThread: true

然后创建一个非常简单的Scheduler调度工厂。

@Configuration
public class QuartzConfiguration {/*** 注册调度器创建工厂*/@Beanpublic Scheduler schedulerFactoryBean() throws Exception {return StdSchedulerFactory.getDefaultScheduler();}
}

添加两个Job Detail,我们要达到的效果是先执行完Job1再执行Job2。两个Job都需要实现Job接口的execute方法,在其中编写业务代码。

@Slf4j
public class TestJob1 implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {log.info("job1被执行,当前时间:" + new Date());}
}
@Slf4j
public class TestJob2 implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {log.info("job2被执行,当前时间:" + new Date());}
}

然后是MVC的分层,这里只写出实现层的代码

@Slf4j
@RequiredArgsConstructor
@Service
public class ServiceImpl implements IService {final Scheduler scheduler;@Overridepublic String addTask() throws SchedulerException {//创建计划链表JobChainingJobListener listener = new JobChainingJobListener("JobLink");JobDetail job1 = JobBuilder.newJob(TestJob1.class).withIdentity("job1", "jg1").build();JobDetail job2 = JobBuilder.newJob(TestJob2.class).withIdentity("job2", "jg1")// 持久存放设置为true,不然Job2只会执行一遍.storeDurably(true).build();CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "tg1").withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).startNow().build();scheduler.addJob(job2, false, true);//设置执行顺序为先执行Job1再执行Job2listener.addJobChainLink(job1.getKey(), job2.getKey());//调度器使用计划链表scheduler.getListenerManager().addJobListener(listener);//安排调度作业scheduler.scheduleJob(job1, trigger);if (!scheduler.isShutdown()) {scheduler.start();}return "success";}
}

这样启动项目后,请求对应的接口,就可以运行起来了。


三、实现Job的动态操作

1、首先需要创建数据库表。在官网[http://www.quartz-scheduler.org/downloads/]下载项目示例后(我是用的quartz-2.3.0-SNAPSHOT),可以在org.quartz.impl.jdbcjobstore包下找到对应数据库的创建语句。
在这里插入图片描述

2、增加更多的接口,这里展示对应的实现类。

// 创建一个cron的任务
@Override
public void addJob(String clazzName, String jobName, String groupName, String cronExp, Map<String, Object> param) {try {// 启动调度器,默认初始化的时候已经启动scheduler.start();//构建job信息Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(clazzName);JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, groupName).build();//表达式调度构建器(即任务执行的时间)CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExp);//按新的cronExpression表达式构建一个新的triggerCronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, groupName).withSchedule(scheduleBuilder).build();//获得JobDataMap,写入数据if (param != null) {trigger.getJobDataMap().putAll(param);}scheduler.scheduleJob(jobDetail, trigger);} catch (Exception e) {log.error("创建任务失败", e);}
}// 暂停任务
@Override
public void pauseJob(String jobName, String groupName) {try {scheduler.pauseJob(JobKey.jobKey(jobName, groupName));} catch (SchedulerException e) {log.error("暂停任务失败", e);}
}// 恢复任务
@Override
public void resumeJob(String jobName, String groupName) {try {scheduler.resumeJob(JobKey.jobKey(jobName, groupName));} catch (SchedulerException e) {log.error("恢复任务失败", e);}
}// 启动一次
@Override
public void runOnce(String jobName, String groupName) {try {scheduler.triggerJob(JobKey.jobKey(jobName, groupName));} catch (SchedulerException e) {log.error("立即运行一次定时任务失败", e);}
}// 更新单个任务
@Override
public void updateJob(String jobName, String groupName, String cronExp, Map<String, Object> param) {try {TriggerKey triggerKey = TriggerKey.triggerKey(jobName, groupName);CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);if (cronExp != null) {// 表达式调度构建器CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExp);// 按新的cronExpression表达式重新构建triggertrigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();}//修改mapif (param != null) {trigger.getJobDataMap().putAll(param);}// 按新的trigger重新设置job执行scheduler.rescheduleJob(triggerKey, trigger);} catch (Exception e) {log.error("更新任务失败", e);}
}// 删除单个任务
@Override
public void deleteJob(String jobName, String groupName) {try {//暂停、移除、删除scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, groupName));scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, groupName));scheduler.deleteJob(JobKey.jobKey(jobName, groupName));} catch (Exception e) {log.error("删除任务失败", e);}
}// 开启所有的任务
@Override
public void startAllJobs() {try {scheduler.start();} catch (Exception e) {log.error("开启所有的任务失败", e);}
}// 暂停所有任务
@Override
public void pauseAllJobs() {try {scheduler.pauseAll();} catch (Exception e) {log.error("暂停所有任务失败", e);}
}// 恢复所有任务
@Override
public void resumeAllJobs() {try {scheduler.resumeAll();} catch (Exception e) {log.error("恢复所有任务失败", e);}
}// 关闭所有的任务
@Override
public void shutdownAllJobs() {try {if (!scheduler.isShutdown()) {// 需谨慎操作关闭scheduler容器// scheduler生命周期结束,无法再 start() 启动schedulerscheduler.shutdown(true);}} catch (Exception e) {log.error("关闭所有的任务失败", e);}
}

需要完整Demo可以在此处下载:https://download.csdn.net/download/qq_40579464/87603431

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_274519.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

golang项目实战2023/03/21

初始化项目首先建立一个文件夹在文件夹下面建一个main.go文件执行初始化命令行go mod init page // page 为自己的项目名称 go mod tidy 安装框架 go get gorm.io/gorm // gorm go get gorm.io/driver/mysql // 这里是用的sql数据库 go get -u github.com/gin-gonic/gin // 这…

Numpy 广播域

NumPy广播(Broadcast)&#xff0c;广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式&#xff0c; 对数组的算术运算通常在相应的元素上进行。不同形状指的是&#xff0c;大小不同当然不是指的维度&#xff0c;但是要求数组各维度的长度相同例如&#xff1a;…

ICG-MAL,吲哚菁绿-马来酰亚胺,CAS:2143933-81-5,科研级别试剂

ICG-MAL,吲哚菁绿-马来酰亚胺 中文名称&#xff1a;吲哚菁绿-马来酰亚胺 英文名称&#xff1a;ICG-MAL 性状&#xff1a;粉末或固体 CAS&#xff1a;2143933-81-5 分子式&#xff1a;C51H56N4O6S 分子量&#xff1a;853.09 溶剂&#xff1a;溶于二氯甲烷等常规性有机溶…

【洛谷刷题】蓝桥杯专题突破-深度优先搜索-dfs(7)

目录 写在前面&#xff1a; 题目&#xff1a;P1596 [USACO10OCT]Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 解题思路&#xff1a; …

【技巧】十大深度学习技巧和经验总结

✅作者简介&#xff1a;在读博士&#xff0c;伪程序媛&#xff0c;人工智能领域学习者&#xff0c;深耕机器学习&#xff0c;交叉学科实践者&#xff0c;周更前沿文章解读&#xff0c;提供科研小工具&#xff0c;分享科研经验&#xff0c;欢迎交流&#xff01;&#x1f4cc;个人…

RocketMQ重复消费问题的原因

文章目录 概览消息发送异常时重复发送消费消息抛出异常消费者提交offset失败服务端持久化offset失败主从同步offset失败重平衡清理长时间消费的消息总结概览 消息发送异常时重复发送 首先,我们来瞅瞅RocketMQ发送消息和消费消息的基本原理。 如图,简单说一下上图中的概念: …

责任链设计模式的一次实践

业务需求 框架&#xff1a;SSH 需要对全部接口的响应体 ResponseBody 做 XSS 拦截 解决方案 在全局拦截器中检测 Response Body 是否有非法字符&#xff0c;如果有&#xff0c;就抛出异常。 实际上&#xff0c;在 struts2 的拦截器上&#xff0c;我发现 即使修改了 action…

yum安装docker以及安装指定版本docker

Docker是Docker.Inc公司开源的一个基于轻量级虚拟化技术的容器引擎项目,整个项目基于Go语言开发&#xff0c;并遵从Apache 2.0协议。通过分层镜像标准化和内核虚拟化技术&#xff0c;Docker使得应用开发者和运维工程师可以以统一的方式跨平台发布应用&#xff0c;并且以几乎没有…

在Java中,使用HttpUtils实现发送HTTP请求

HTTP请求&#xff0c;在日常开发中&#xff0c;还是比较常见的&#xff0c;今天给大家分享HttpUtils如何使用。 阅读本文&#xff0c;你将收获&#xff1a; 简单总结HTTP请求常用配置&#xff1b;JavaLib中HttpUtils如何使用&#xff1b;如何封装HTTP请求工具类。 第一部分&a…

【Unity入门】3D物体

【Unity入门】3D物体 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;物体移动旋转缩放 &#xff08;1&#xff09;物体移动 在上一篇文章【Unity入门】场景视图操作我们学会了在场景中创建3…

开源供应链管理系统 S2B2B2C系统方案及源码输出

连锁供应链的管理&#xff0c;包括供应链的仓库管理、业务员管理、门店订货管理、门店管理、门店前端拓客管理&#xff0c;相关的功能结构图如下&#xff1a; 整个方案含PC、小程序端&#xff0c;源码&#xff01; 功能列表&#xff1a; 仓库管理&#xff1a;包括仓库布局、库存…

Fabric系列 - TLS身份验证

排序节点&#xff08;Orderer&#xff09;要启用TLS身份验证 对等节点&#xff08;Peer&#xff09;要启用TLS的身份验证 Gossip 消息传递 gossip 层使用 TLS 绑定来验证连接另一端的对等方的身份。 通过 Peer 节点 TLS 层来处理点对点消息的安全性&#xff0c;不需要使用签名…

OpenAI创始人:GPT-4的研究起源和构建心法

OneFlow编译 翻译&#xff5c;杨婷、贾川、徐佳渝 三十年前&#xff0c;互联网&#xff08;Web 1.0&#xff09;时代开启。人们只能在笨重的电脑上用鼠标点击由HTML编写的网页文本&#xff0c;随后开始支持插入图片&#xff0c;可以上传视频&#xff0c;于是有了网络新闻、搜索…

一次小破站JS代码审计出XSS漏洞思路学习

今天看了小破站一个大佬的分析&#xff0c;感觉思路很有意思&#xff0c;感兴趣的xdm可以到大佬视频下提供的链接进行测试&#xff08;传送门&#xff09;这类社交平台的XSS漏洞利用起来其实危害是特别大的&#xff0c;利用XSS能在社交平台上呈现蠕虫式的扩散&#xff0c;大部分…

【人人都能读标准】10. 作用域链与闭包

本文为《人人都能读标准》—— ECMAScript篇的第10篇。我在这个仓库中系统地介绍了标准的阅读规则以及使用方式&#xff0c;并深入剖析了标准对JavaScript核心原理的描述。 在8.执行环境我们说过&#xff0c;由ECMAScript代码创建的执行上下文会有一个词法环境的组件&#xff0…

【Effective C++详细总结】第四章 设计与声明

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;C/C知识点 &#x1f4e3;专栏定位&#xff1a;整理一下 C 相关的知识点&#xff0c;供大家学习参考~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;…

Flink-转换算子

基本转换算子 map(映射) filter&#xff08;过滤&#xff09; flatMap&#xff08;扁平映射&#xff09; 聚合算子 keyBy&#xff08;按键分区&#xff09; 简单聚合 reduce&#xff08;归约聚合&#xff09; UDF介绍 函数类 富函数类 数据源读入数据之后&#xff0c;我们就可…

Neodynamic EPLPrinter SDK 2.0 for .NET Crack

Neodynamic EPLPrinter Emulator SDK for .NET Standard V2.0 添加对 FK&#xff08;删除表单&#xff09;、FR&#xff08;检索表单&#xff09;和 FS&#xff08;存储表单&#xff09;表单相关命令的支持。 21月 2023&#xff0c; 10 - 34&#xff1a;<>新版本 特征…

如何在24小时内让你的网站跻身谷歌前列?

在当今互联网时代&#xff0c;拥有一个排名靠前的网站对于企业来说非常重要&#xff0c;因为这意味着更多的流量和更高的曝光率。 而谷歌&#xff08;Google&#xff09;是全球最受欢迎的搜索引擎之一&#xff0c;因此在谷歌的搜索结果中排名靠前非常重要。 那么如何在24小时…

tomcat服务器前端部署【Tomcat Manager、思路分析】

问题描述 当前需要我进行前端代码的部署&#xff0c;但是我忘记了这个系统对应的部署位置&#xff0c;但是隐约记得好像是通过tomcat部署的。 然后当时为了方便部署&#xff0c;我们打开了Tomcat Manager 以下是基于Tomcat Manager的&#xff0c;没有打开的需要前往tomcat下载…