SpringBoot定时任务+Quartz 动态调度

1、分部解释
2、完整代码
3、SpringBoot定时任务+Quartz

1、动态定时任务:

  • 动态定时任务,即定时任务的动态调度,可根据需求自由的进行任务的生成、暂停、恢复、删除和更新操作。
  • Quartz本身没有提供动态调度的功能,需要自己根据相关的API开发。

2、动态定时任务使用场景:

  • 订单成功后自动发短信通知
  • 每日推送的功能引发用户不满,不再定时推送
  • 每日下班前30分钟发送工作报表,遇节假日暂停发送

3、Scheduler调度器常用API

在这里插入图片描述

4、实现动态调度的定时任务

在这里插入图片描述
注释:
JobBean:封装,任务调度的参数,不在使用默认的调度方式。

代码演示:
1、JobBean 类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class JobBean {
    //任务名字
    private String jobName;
    //任务类,(自己任务,实现类的全类名) --->任务类.class.getName()
    private String jobClass;
    //cron表达式
    private String cronExpression;
}

2、创建一个工具类:

2.1、创建定时任务:

    //创建任务
    public static void createJob(Scheduler scheduler, JobBean jobBean) {
        //通过类的名字获取类
        Class<? extends Job> jobClass = null;
        CronTrigger trigger =null;
        JobDetail jobDetail =null;
        try {
            jobClass = (Class<? extends Job>) Class.forName(jobBean.getJobClass());
                    jobDetail = JobBuilder.newJob(jobClass)
                    .storeDurably()
                    //唯一标识
                    .withIdentity(jobBean.getJobName())
                    .build();
            //创建触发器
                    trigger = TriggerBuilder.newTrigger()
                    .forJob(jobDetail)
                    //唯一标识和上面的JobDetail是配对的。当然写别的名称也是可以的,就是一个标识
                    .withIdentity(jobBean.getJobName())
                    //这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。
                    //每两秒钟执行一次
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression()))
                    .build();
            //需要 JobDetail var1, Trigger var2 这两个参数
                scheduler.scheduleJob(jobDetail, trigger);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

2.2、暂停任务:

 //暂停任务
    public static void pauseJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.pauseJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

2.3、恢复任务:

    //恢复任务
    public static void resumeJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.resumeJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);

    }
        }

2.4、删除任务:

    //删除任务
    public static void deleteJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.deleteJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);

    }
        }

2.5、执行一次任务

 //执行一次任务
        public static void runOnce(Scheduler scheduler, String jobName) {
            try {
                scheduler.triggerJob(JobKey.jobKey(jobName));
            } catch (SchedulerException e) {
                throw new RuntimeException(e);

        }
            }

2.6、修改任务

 //修改任务
    public static void updateJob(Scheduler scheduler, JobBean jobBean) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobBean.getJobName());
            //强制转换成CronTrigger
            CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//             oldTrigger.getTriggerBuilder();  将老的trigger返回出来
            CronTrigger newTrigger = oldTrigger.getTriggerBuilder()
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression())).build();
            scheduler.rescheduleJob(triggerKey,newTrigger);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
    }
        }

5、编写控制器方法:

在这里插入图片描述

完整代码:

1、pom文件

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

2、任务调度需要参数类(封装参数类 POJO)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class JobBean {
    //任务名字
    private String jobName;
    //任务类,(自己任务,实现类的全类名) --->任务类.class.getName()
    private String jobClass;
    //cron表达式
    private String cronExpression;
}

3、工具类:

public class DynJobUtil {
    //创建任务
    public static void createJob(Scheduler scheduler, JobBean jobBean) {
        //通过类的名字获取类
        Class<? extends Job> jobClass = null;
        CronTrigger trigger =null;
        JobDetail jobDetail =null;
        try {
            jobClass = (Class<? extends Job>) Class.forName(jobBean.getJobClass());
                    jobDetail = JobBuilder.newJob(jobClass)
                    .storeDurably()
                    //唯一标识
                    .withIdentity(jobBean.getJobName())
                    .build();
            //创建触发器
                    trigger = TriggerBuilder.newTrigger()
                    .forJob(jobDetail)
                    //唯一标识和上面的JobDetail是配对的。当然写别的名称也是可以的,就是一个标识
                    .withIdentity(jobBean.getJobName())
                    //这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。
                    //每两秒钟执行一次
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression()))
                    .build();
            //需要 JobDetail var1, Trigger var2 这两个参数
                scheduler.scheduleJob(jobDetail, trigger);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }
    //暂停任务
    public static void pauseJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.pauseJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }
    //恢复任务
    public static void resumeJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.resumeJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);

    }
        }
    //删除任务
    public static void deleteJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.deleteJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);

    }
        }
    //执行一次任务
        public static void runOnce(Scheduler scheduler, String jobName) {
            try {
                scheduler.triggerJob(JobKey.jobKey(jobName));
            } catch (SchedulerException e) {
                throw new RuntimeException(e);

        }
            }
    //修改任务
    public static void updateJob(Scheduler scheduler, JobBean jobBean) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobBean.getJobName());
            //强制转换成CronTrigger
            CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//             oldTrigger.getTriggerBuilder();  将老的trigger返回出来
            CronTrigger newTrigger = oldTrigger.getTriggerBuilder()
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression())).build();
            scheduler.rescheduleJob(triggerKey,newTrigger);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
    }
        }
}

4、自己的任务

@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("任务开始执行");
        JobDetail jobDetail = context.getJobDetail();
        System.out.println("名字" + jobDetail.getKey().getName());
        System.out.println("类名--->" + jobDetail.getJobClass().getName());
        System.out.println("本次执行的时间为---》" + context.getFireTime());
        System.out.println("下次执行的时间为---》" + context.getNextFireTime());
        System.out.println("任务执行完毕");
        System.out.println("============================");
    }
}

5、进行测试:

@Slf4j
@Controller
@RequestMapping("/job")
public class DynJob {

    @Autowired
    private Scheduler scheduler;

    JobBean jobBean = new JobBean("jobDetail",MyJob.class.getName(),"0/5 * * * * ?");
    //创建任务
    @GetMapping("/createJob")
            public void createJob(){
        log.info("jobBean:{}",jobBean);
        log.info("创建任务");
        DynJobUtil.createJob(scheduler,jobBean);
    }
        //暂停任务
        @GetMapping("/pauseJob")
        public void pauseJob(){
            JobBean jobBean = new JobBean("jobDetail","jobClass","0/5 * * * * ?");

            log.info("jobBean:{}",jobBean);
            log.info("暂停任务");
            DynJobUtil.pauseJob(scheduler,jobBean.getJobName());
        }
        //恢复任务
    @GetMapping("/resumeJob")
    public void resumeJob(){
        log.info("jobBean:{}", jobBean);
        log.info("恢复任务");
        DynJobUtil.resumeJob(scheduler, jobBean.getJobName());

    }
    //删除任务
    @GetMapping("/deleteJob")
    public void deleteJob(){
        log.info("jobBean:{}", jobBean);
        log.info("删除任务");
        DynJobUtil.deleteJob(scheduler, jobBean.getJobName());
    }
    //执行一次任务,暂停之后就是执行一次,之后不在执行
    @GetMapping("/runJob")
    public void runJob(){
        log.info("jobBean:{}", jobBean);
        log.info("执行一次任务");
        DynJobUtil.runOnce(scheduler, jobBean.getJobName());
    }
    //修改任务
    @GetMapping("/modifyJob")
    public void modifyJob() {
        jobBean.setCronExpression("0/2 * * * * ?");
        log.info("jobBean:{}", jobBean);
        log.info("修改任务");
        DynJobUtil.updateJob(scheduler, jobBean);
    }
}

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

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

相关文章

Github 2024-06-06 Go开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-06统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10Ollama: 本地大型语言模型设置与运行 创建周期:248 天开发语言:Go协议类型:MIT LicenseStar数量:42421 个Fork数量:2724 次关注人…

小程序丨最大填表限制如何开启?

老师在新建填表时&#xff0c;希望设置最大数量限制&#xff0c;若填表达到限制&#xff0c;后续的学生将不能继续提交填表。 通过开启【表格最大限制】功能即可实现&#xff0c;下面就来教大家如何制作吧。 &#x1f50e;如何开启表格最大限制功能&#xff1f; 按照常规流程…

探索 LLM 预训练的挑战,GPU 集群架构实战

万卡 GPU 集群实战&#xff1a;探索 LLM 预训练的挑战 一、背景 在过往的文章中&#xff0c;我们详细阐述了LLM预训练的数据集、清洗流程、索引格式&#xff0c;以及微调、推理和RAG技术&#xff0c;并介绍了GPU及万卡集群的构建。然而&#xff0c;LLM预训练的具体细节尚待进一…

Web安全:Web体系架构存在的安全问题和解决方案

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…

word2016版本中同时显示多个页面

为了方便查看word内容&#xff0c;我们会将多个页面同时显示。 对于2016版&#xff0c;操作方法如下&#xff1a; 视图 ---》多页

上海亚商投顾:沪指震荡下跌 两市成交不足7000亿元

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡调整&#xff0c;创业板指冲高回落。车路云概念股持续活跃&#xff0c;万通智控、鸿泉物联、华体…

AI炒股:获取个股的历史成交价格并画出K线图

任务&#xff1a;获取贵州茅台的近几个月的价格数据&#xff0c;绘制k线图&#xff1b; 在deepseek中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个编写Python脚本的任务&#xff0c;具体步骤如下&#xff1a; 用AKShare库获取股票贵州茅台&#xf…

超级详细Spring AI运用Ollama大模型

大模型工具Ollama 官网:https://ollama.com/ Ollama是一个用于部署和运行各种开源大模型的工具; 它能够帮助用户快速在本地运行各种大模型&#xff0c;极大地简化了大模型在本地运行的过程。用户通过执行几条命令就能在本地运行开源大模型&#xff0c;如Lama 2等; 综上&#x…

【毕业设计之微信小程序系列】基于微信小程序的餐厅点餐小程序的设计与实现

《基于微信小程序的餐厅点餐小程序的设计与实现》 项目效果图 目录大纲 摘要 1、选题及其意义 1.1、设计项目的名称 1.2、研究意义 2、需求分析 2.1、用户需求分析 2.2、功能需求分析 2.3、非功能需求分析 3、系统相关技术概述 3.1、餐饮平台开发相关技术 3.1.1、微信小程序 …

适用于 Windows 的 8 大数据恢复软件

数据恢复软件可帮助您恢复因意外删除或由于某些技术故障&#xff08;如硬盘损坏等&#xff09;而丢失的数据。这些工具可帮助您从硬盘驱动器 (HDD) 中高效地恢复丢失的数据&#xff0c;因为这些工具不支持从 SSD 恢复数据。重要的是要了解&#xff0c;您删除的数据不会被系统永…

NAT端口映射,实现外网访问内网服务器

目录 前言一、搭建网络拓扑1.1 配置server和pc1.1.1 配置server01.1.2 配置server11.1.3 配置pc0 1.2 配置客户路由器1.2.1 配置路由器IP1.2.2 配置静态路由 1.3 配置ISP路由器 二、配置端口映射2.1 在客户路由器配置端口映射2.2 测试公网计算机访问私网服务器2.2.1 PC0向serve…

一个简单的方式看看MySQL的锁

突然发现半个月没写了。最近事情太多了。 在日常工作的处理问题的过程中&#xff0c;我发现了一个简单的论证锁的问题&#xff0c;以前我讲的有点复杂&#xff0c;看来应该去改改之前的讲法了。 首先构造一个无主键无索引的表。并且初始化5条数据。 场景A&#xff1a; RR隔离…

珈和科技携手浙江省气候中心,打造农业气象数字化服务新标杆!

古谚有云&#xff1a;春耕夏种秋收冬藏&#xff0c;皆在天时。可天有不测风云&#xff0c;农有“旦夕祸福”。寒潮、干旱、洪涝等气象灾害频繁发生&#xff0c;给农业生产带来了巨大挑战。 气候变化直接影响着农业生产&#xff0c;数字化时代&#xff0c;如何依靠科技手段降低…

【UML用户指南】-08-对基本结构建模-图

目录 1、41视图 2、术语和概念 3、结构图 &#xff08;1&#xff09;类图&#xff08;class diagram&#xff09;&#xff1a; &#xff08;2&#xff09;构件图&#xff1a;&#xff08;component diagram&#xff09; &#xff08;3&#xff09;组合结构图&#xff1a;…

“Apache Kylin 实战指南:从安装到高级优化的全面教程

Apache Kylin是一个开源的分布式分析引擎,它提供了在Hadoop/Spark之上的SQL查询接口及多维分析(OLAP)能力,支持超大规模数据的亚秒级查询。以下是Kylin的入门教程,帮助您快速上手并使用这个强大的工具。 1. 安装Kylin Apache Kylin的安装是一个关键步骤,它要求您具备一…

[Algorithm][动态规划][两个数组的DP][最长公共子序列][不相交的线][不同的子序列][通配符匹配]详细讲解

目录 1.最长公共子序列1.题目链接2.算法原理详解3.代码实现 2.不相交的线1.题目链接2.算法原理详解3.代码实现 3.不同的子序列1.题目链接2.算法原理详解3.代码实现 4.通配符匹配1.题目链接2.算法原理详解3.代码实现 1.最长公共子序列 1.题目链接 最长公共子序列 2.算法原理详…

读AI未来进行式笔记04数字医疗与机器人

1. 数字医疗 1.1. 20世纪的“现代医学”得益于史无前例的科学突破&#xff0c;使得医疗的方方面面都得到改善&#xff0c;让人类预期寿命从1900年的31岁提高到2017年的72岁 1.2. 现有的医疗数据库和流程将实现数字化 1.2.1. 患者记录 1.2.…

[flutter]一键将YAPI生成的api.json文件转为需要的Dart Model类的脚本

目的&#xff1a; 根据YAPI接口平台生成的api.json接口文件&#xff0c;将接口数据转化为model类&#xff0c;生成对应的接口值类型文件。 发现&#xff1a; api.json文件导出&#xff1a; YAPi是一个接口管理平台&#xff0c;登录账号打开项目后&#xff0c;在点击数据管理…

AJAX 跨域

这里写目录标题 同源策略JSONPJSONP 是怎么工作的JSONP 的使用原生JSONP实践CORS 同源策略 同源&#xff1a; 协议、域名、端口号 必须完全相同、 当然网页的URL和AJAX请求的目标资源的URL两者之间的协议、域名、端口号必须完全相同。 AJAX是默认遵循同源策略的&#xff0c;不…