SpringBoot+quartz实现定时任务的创建、删除、查询操作
1、在pom.xml文件中导入quartz的依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>
2、配置quartz的数据源等操作
package com.train.batch.config;import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;import javax.sql.DataSource;
import java.io.IOException;@Configuration
public class SchedulerConfig {@Resourceprivate MyJobFactory myJobFactory;@Beanpublic SchedulerFactoryBean schedulerFactoryBean(@Qualifier("dataSource") DataSource dataSource) throws IOException {SchedulerFactoryBean factory = new SchedulerFactoryBean();factory.setDataSource(dataSource);factory.setJobFactory(myJobFactory);// 启动之后2秒后可以执行factory.setStartupDelay(2);return factory;}
}
需要对父类的方法进行重写。
package com.train.batch.config;import jakarta.annotation.Resource;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.stereotype.Component;@Component
public class MyJobFactory extends SpringBeanJobFactory {@Resourceprivate AutowireCapableBeanFactory beanFactory;/*** 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire。*/@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {Object jobInstance = super.createJobInstance(bundle);beanFactory.autowireBean(jobInstance);return jobInstance;}
}
3、并发执行:上一周期还没执行完,下一周期又开始了
禁止任务并发执行,只需要在类上加一个注解(@DisallowConcurrentExecution)
4、controller类,
做调度问题,不应该把任务写在配置类里面,应该用控制台增加,以下的文件直接拿来用就行。
package com.train.batch.job;import com.train.batch.req.CronJobReq;
import com.train.batch.resp.CronJobResp;
import com.train.common.resp.CommonResp;import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.Date;
import java.util.List;@RestController
@RequestMapping(value = "/admin/job")
public class JobController {private static Logger LOG = LoggerFactory.getLogger(JobController.class);@Autowiredprivate SchedulerFactoryBean schedulerFactoryBean;@RequestMapping(value = "/run")public CommonResp<Object> run(@RequestBody CronJobReq cronJobReq) throws SchedulerException {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();LOG.info("手动执行任务开始:{}, {}", jobClassName, jobGroupName);// 任务只执行一次schedulerFactoryBean.getScheduler().triggerJob(JobKey.jobKey(jobClassName, jobGroupName));return new CommonResp<>();}@RequestMapping(value = "/add")public CommonResp add(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();String cronExpression = cronJobReq.getCronExpression();String description = cronJobReq.getDescription();LOG.info("创建定时任务开始:{},{},{},{}", jobClassName, jobGroupName, cronExpression, description);CommonResp commonResp = new CommonResp();try {// 通过SchedulerFactory获取一个调度器实例Scheduler sched = schedulerFactoryBean.getScheduler();// 启动调度器sched.start();//构建job信息JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(jobClassName)).withIdentity(jobClassName, jobGroupName).build();//表达式调度构建器(即任务执行的时间)CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);//按新的cronExpression表达式构建一个新的triggerCronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName).withDescription(description).withSchedule(scheduleBuilder).build();sched.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {LOG.error("创建定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("创建定时任务失败:调度异常");} catch (ClassNotFoundException e) {LOG.error("创建定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("创建定时任务失败:任务类不存在");}LOG.info("创建定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value = "/pause")public CommonResp pause(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();LOG.info("暂停定时任务开始:{},{}", jobClassName, jobGroupName);CommonResp commonResp = new CommonResp();try {Scheduler sched = schedulerFactoryBean.getScheduler();sched.pauseJob(JobKey.jobKey(jobClassName, jobGroupName));} catch (SchedulerException e) {LOG.error("暂停定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("暂停定时任务失败:调度异常");}LOG.info("暂停定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value = "/resume")public CommonResp resume(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();LOG.info("重启定时任务开始:{},{}", jobClassName, jobGroupName);CommonResp commonResp = new CommonResp();try {Scheduler sched = schedulerFactoryBean.getScheduler();sched.resumeJob(JobKey.jobKey(jobClassName, jobGroupName));} catch (SchedulerException e) {LOG.error("重启定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("重启定时任务失败:调度异常");}LOG.info("重启定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value = "/reschedule")public CommonResp reschedule(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();String cronExpression = cronJobReq.getCronExpression();String description = cronJobReq.getDescription();LOG.info("更新定时任务开始:{},{},{},{}", jobClassName, jobGroupName, cronExpression, description);CommonResp commonResp = new CommonResp();try {Scheduler scheduler = schedulerFactoryBean.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);// 表达式调度构建器CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);CronTriggerImpl trigger1 = (CronTriggerImpl) scheduler.getTrigger(triggerKey);trigger1.setStartTime(new Date()); // 重新设置开始时间CronTrigger trigger = trigger1;// 按新的cronExpression表达式重新构建triggertrigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withDescription(description).withSchedule(scheduleBuilder).build();// 按新的trigger重新设置job执行scheduler.rescheduleJob(triggerKey, trigger);} catch (Exception e) {LOG.error("更新定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("更新定时任务失败:调度异常");}LOG.info("更新定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value = "/delete")public CommonResp delete(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();LOG.info("删除定时任务开始:{},{}", jobClassName, jobGroupName);CommonResp commonResp = new CommonResp();try {Scheduler scheduler = schedulerFactoryBean.getScheduler();scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName, jobGroupName));scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName, jobGroupName));scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));} catch (SchedulerException e) {LOG.error("删除定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("删除定时任务失败:调度异常");}LOG.info("删除定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value="/query")public CommonResp query() {LOG.info("查看所有定时任务开始");CommonResp commonResp = new CommonResp();List<CronJobResp> cronJobDtoList = new ArrayList();try {Scheduler scheduler = schedulerFactoryBean.getScheduler();for (String groupName : scheduler.getJobGroupNames()) {for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {CronJobResp cronJobResp = new CronJobResp();cronJobResp.setName(jobKey.getName());cronJobResp.setGroup(jobKey.getGroup());//get job's triggerList<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);CronTrigger cronTrigger = (CronTrigger) triggers.get(0);cronJobResp.setNextFireTime(cronTrigger.getNextFireTime());cronJobResp.setPreFireTime(cronTrigger.getPreviousFireTime());cronJobResp.setCronExpression(cronTrigger.getCronExpression());cronJobResp.setDescription(cronTrigger.getDescription());Trigger.TriggerState triggerState = scheduler.getTriggerState(cronTrigger.getKey());cronJobResp.setState(triggerState.name());cronJobDtoList.add(cronJobResp);}}} catch (SchedulerException e) {LOG.error("查看定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("查看定时任务失败:调度异常");}commonResp.setContent(cronJobDtoList);LOG.info("查看定时任务结束:{}", commonResp);return commonResp;}}
5、DOM类的相关定义
public class CronJobReq {private String group;private String name;private String description;private String cronExpression;@Overridepublic String toString() {final StringBuffer sb = new StringBuffer("CronJobDto{");sb.append("cronExpression='").append(cronExpression).append('\'');sb.append(", group='").append(group).append('\'');sb.append(", name='").append(name).append('\'');sb.append(", description='").append(description).append('\'');sb.append('}');return sb.toString();}public String getGroup() {return group;}public void setGroup(String group) {this.group = group;}public String getCronExpression() {return cronExpression;}public void setCronExpression(String cronExpression) {this.cronExpression = cronExpression;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;import java.util.Date;@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class CronJobResp {private String group;private String name;private String description;private String state;private String cronExpression;@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")private Date nextFireTime;@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")private Date preFireTime;@Overridepublic String toString() {final StringBuffer sb = new StringBuffer("CronJobDto{");sb.append("cronExpression='").append(cronExpression).append('\'');sb.append(", group='").append(group).append('\'');sb.append(", name='").append(name).append('\'');sb.append(", description='").append(description).append('\'');sb.append(", state='").append(state).append('\'');sb.append(", nextFireTime=").append(nextFireTime);sb.append(", preFireTime=").append(preFireTime);sb.append('}');return sb.toString();}public String getGroup() {return group;}public void setGroup(String group) {this.group = group;}public String getCronExpression() {return cronExpression;}public void setCronExpression(String cronExpression) {this.cronExpression = cronExpression;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getNextFireTime() {return nextFireTime;}public void setNextFireTime(Date nextFireTime) {this.nextFireTime = nextFireTime;}public Date getPreFireTime() {return preFireTime;}public void setPreFireTime(Date preFireTime) {this.preFireTime = preFireTime;}public String getState() {return state;}public void setState(String state) {this.state = state;}
}
相关文章:
SpringBoot+quartz实现定时任务的创建、删除、查询操作
1、在pom.xml文件中导入quartz的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency> 2、配置quartz的数据源等操作 package com.train.batch.config;imp…...

Oracle的学习心得和知识总结(二十八)|Oracle数据库数据库回放功能之论文二翻译及学习
目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《Oracle Database SQL Language Reference》 2、参考书籍:《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…...
排序算法:归并排序
约翰冯诺伊曼在 1945 年提出了归并排序。在讲解归并排序之前,我们先一起思考一个问题:如何将两个有序的列表合并成一个有序的列表? 将两个有序的列表合并成一个有序的列表 这太简单了,笔者首先想到的思路就是,将两个列…...
Hbase-技术文档-spring-boot整合使用hbase--简单操作增删改查--提供封装高可用的模版类
使用spring-boot项目来整合使用hbase。 引入依赖 <dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>2.4.3</version> </dependency> 依赖声明表示将把Apache HBase客户端库…...

基于Pytorch的神经网络部分自定义设计
一、基础概念(学习笔记) (1)训练误差和泛化误差[1] 本质上,优化和深度学习的目标是根本不同的。前者主要关注的是最小化目标,后者则关注在给定有限数据量的情况下寻找合适的模型。训练误差和泛化误差通常不…...
持续更新串联记忆English words
(一)这是一组关于“服装搭配”的单词。通过在记忆中检索,回忆起隐藏的信息吧~ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>今日单词>>&…...
postgresql 内核源码分析 btree索引的增删查代码基本原理流程分析,索引膨胀的原因在这里
B-Tree索引代码流程分析 专栏内容: postgresql内核源码分析手写数据库toadb并发编程 开源贡献: toadb开源库 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤&…...

详细了解G1、了解G1、G1垃圾收集器详解、G1垃圾回收器简单调优
4.详细了解G1: 4.1.一:什么是垃圾回收 4.2.了解G1 4.3.G1 Yong GC 4.4.G1 Mix GC 4.5.三色标记算法 4.6.调优实践 5.G1垃圾收集器详解 5.1.G1垃圾收集器 5.2.G1的堆内存划分 5.3.G1的运行过程 5.4.三色标记 5.4.1.漏标问题 5.5.记忆集与卡表 5.6.安全点与…...
vue项目中 package.json 详解
在 Vue 项目中,package.json 是一个重要的配置文件,它包含了项目的名称、版本、作者、依赖等信息。下面是一份详细的 Vue 项目 package.json 配置说明: 1.name:项目的名称,用于标识项目,例如:&q…...

为什么要进行管网水位监测,管网水位监测的作用是什么
管网水位监测是城市排水系统管理的重要手段,对于保障城市排水设施安全运行和提升城市管理水平具有重要意义。通过对排水管网的水位进行实时监测和分析,能够及时发现问题并采取措施,提高排水系统的运行效率和管理水平。本文将详细介绍为什么要…...
webpack学习笔记
1. webpack基本概念 webpack: JavaScript 应用程序的静态模块打包器,是目前最为流行的JavaScript打包工具之一。webpack会以一个或多个js文件为入口,递归检查每个js模块的依赖,从而构建一个依赖关系图,然后依据该关系…...

解析代理IP在跨境电商和社媒营销中的关键作用
跨境电商和社媒营销领域的从业者深知,代理IP的价值愈发凸显。在推广营销的过程中,频繁遇到因IP关联而封禁账号的情况,或因使用不安全IP而导致异常问题。 这些问题促使人们开始高度重视代理IP的作用。但实际上,代理IP究竟是何物&a…...

Unity 之 Start 与Update 方法的区别
文章目录 当谈论Unity中的 Start和 Update方法时,我们实际上是在讨论MonoBehaviour类中的两个常用方法,用于编写游戏逻辑。这两个方法在不同的时机被调用,因此您可以根据需要选择在哪个方法中编写特定的代码。 Start 方法: Start…...
Spring Boot中如何编写优雅的单元测试
单元测试是指对软件中的最小可测试单元进行检查和验证。在Java中,单元测试的最小单元是类。通过编写针对类或方法的小段代码,来检验被测代码是否符合预期结果或行为。执行单元测试可以帮助开发者验证代码是否正确实现了功能需求,以及是否能够…...

三星Galaxy S23与iPhone 15的对比分析:谁会胜出?
三星Galaxy S23与iPhone 15的对决将于下个月进入高潮,这将是今年智能手机中最大的一场较量。毕竟,这是两家领先的移动设备制造商的旗舰手机。他们的手机的比较将在很大程度上决定谁能获得最佳手机的称号。 我们已经知道有利于三星Galaxy S23的情况,该产品自春季以来一直在推…...

MySQL索引 事物 存储引擎
一 索引 索引的概念 索引就是一种帮助系统能够更快速的查找信息的结构 索引的作用 索引的副作用 创建索引的规则 MySQL的优化 哪些字段/场景适合创建索引 哪些不适合 小字段唯一性强的字段更新不频繁,但查询率比较高的字段表记录超过 300行主键,外键…...
【谷粒学院】报错记录
无法从Nacos获取动态配置 原先gulimall-common中SpringCloud Alibaba的版本是2.1.0.RELEASE,无法从Nacos中获取配置文件信息 <dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId&…...

微积分基本概念
微分 函数的微分是指对函数的局部变化的一种线性描述。微分可以近似地描述当函数自变量的取值作足够小的改变时,函数的值是怎样改变的。。对于函数 y f ( x ) y f(x) yf(x) 的微分记作: d y f ′ ( x ) d x d_y f^{}(x)d_x dyf′(x)dx 微分和…...

【业务功能篇78】微服务-前端后端校验- 统一异常处理-JSR-303-validation注解
5. 前端校验 我们在前端提交的表单数据,我们也是需要对提交的数据做相关的校验的 Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可 校验的页面效果 前端数据…...

pytorch的用法
...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...