SpringBoot定时任务+Quartz 动态调度

news2024/11/18 13:39:39

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);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:美团小袋自动配送车

大型电商公司美团已选用NVIDIA Jetson AGX Xavier 平台&#xff0c;作为无人配送机器人核心AI算力。 美团点评是全球大型的按需食品配送公司&#xff0c;结合了Uber Eats、Yelp和Groupon的商业模式&#xff0c;与超过40万家本地企业开展合作。他们推出了小袋自动配送车&#…

Hive3.1.2分区与排序(内置函数)

Hive3.1.2分区与排序&#xff08;内置函数&#xff09; 1、Hive分区(十分重要&#xff01;&#xff01;) 分区的目的&#xff1a;避免全表扫描&#xff0c;加快查询速度&#xff01; 在大数据中&#xff0c;最常见的一种思想就是分治&#xff0c;我们可以把大的文件切割划分成…

【InternLM实战营第二期笔记】05:LMDeploy 量化部署 LLM 实践

文章目录 课程背景常见部署方法LMDeploy安装、部署、量化量化默认比例 KV cachecache-max-entry-count0.5cache-max-entry-count0.014bit 量化 Serve a model启动服务链接 API 服务器网页客户端访问服务器 API 代码集成Python 代码运行 1.8B 模型向 TurboMind 后端传递参数 拓展…

AOP案例

黑马程序员JavaWeb开发教程 文章目录 一、案例1.1 案例1.2 步骤1.2.1 准备1.2.2 编码 一、案例 1.1 案例 将之前案例中增、删、改相关节后的操作日志记录到数据库表中。 操作日志&#xff1a;日志信息包含&#xff1a;操作人、操作时间、执行方法的全类名、执行方法名、方法…

苍穹外卖笔记-02-借助小乌龟创建gitee仓库,apifox代替YApi,Swagger

TOC 1 借助小乌龟创建gitee苍穹外卖仓库 这里建议看视频bilibili比特鹏哥视频 使用软件 git TortoiseGit https://git-scm.com/downloads https://tortoisegit.org/ 使用代码托管平台gitee&#xff0c;git的使用和gitee的账号创建需要查询其他资料 在一个从未克隆仓库的…

yolov8-obb 旋转目标检测 瑞芯微RKNN芯片部署、地平线Horizon芯片部署、TensorRT部署

特别说明&#xff1a;参考官方开源的yolov8代码、瑞芯微官方文档、地平线的官方文档&#xff0c;如有侵权告知删&#xff0c;谢谢。 模型和完整仿真测试代码&#xff0c;放在github上参考链接 模型和代码。 折腾旋转目标检测的小伙伴们看过来&#xff0c;yolov8旋转目标检测部署…

ShowDoc item_id 未授权SQL注入漏洞复现

0x01 产品简介 ShowDoc 是一个开源的在线文档协作平台,它支持Markdown、图片等多种格式,方便团队成员共同编辑和分享文档。企业常见使用场景是使用其进行接口文档、内部知识库管理。 0x02 漏洞概述 2024年6月,ShowDoc官方发布新版本修复了一个SQL注入漏洞。鉴于该漏洞无前…

速通数据挖掘课程

速通 数据挖掘课程 大的分类 标签预测&#xff08;分类&#xff09; 和 数值预测&#xff08;预测呀&#xff09; 监督 非监督 是否 需要预先训练模型 然后预测 聚类&#xff1a;拿一个比一个&#xff0c;看看相似否&#xff0c;然后归一类 数据四种类型 数据属性有四种&…

C++实现,简单的命令行交互框架

目录 背景背景 在实际开发中,经常需要有对端测试程序,配合自己的程序,验证功能、逻辑等。面对繁杂、多变的需求,如果对端程序设计得不够灵活,则无法提升工作效率,如果能够与对端程序交互,通过命令行输入命令的方式完成测试验证,将大大提升工作效率,下面的示例程序是一…

weak的底层原理

weak 引用在 iOS 中通过维护一个全局的弱引用表来实现。当弱引用的对象被释放时&#xff0c;所有指向它的弱引用会被自动置为 nil&#xff0c;从而防止悬挂指针。 弱引用表&#xff08;Weak Table&#xff09;的键和值 理解弱引用表的键和值对于理解 weak 引用的底层机制非常重…

酱菜产业:传承美味,点亮生活

酱菜&#xff0c;这道深受人们喜爱的传统美食&#xff0c;以其独特的风味和营养价值&#xff0c;点亮了我们的日常生活。酱菜产业作为美食文化的重要组成部分&#xff0c;正以其独特的魅力&#xff0c;吸引着越来越多的消费者。 酱菜产业的赵总说&#xff1a;酱菜的制作过程&am…

Nginx网站服务【☆☆☆】

市面上常用Linux的web服务器&#xff1a;apache、Nginx。 apache与nginx的区别&#xff1f; 最核心的区别在于NGINX采用异步非阻塞机制&#xff0c;多个连接可以对应一个进程&#xff1b;apache采用的是同步阻塞多进程/线程模型&#xff0c;一个连接对应一个进程。apache美国…

【C语言】一节课拿捏---动态内存分配

谢谢观看&#xff01;希望以下内容帮助到了你&#xff0c;对你起到作用的话&#xff0c;可以一键三连加关注&#xff01;你们的支持是我更新地动力。 因作者水平有限&#xff0c;有错误还请指出&#xff0c;多多包涵&#xff0c;谢谢&#xff01; 目录 一、 为什么要有动态内存…

关于IDEA创建Maven一直爆红无法下载的问题

你能看到这我就知道你肯定已经试过了网上的很多方法了&#xff0c;我之前也是&#xff0c;试过了很多一直无法正常下载&#xff0c;我也是找人给 线下看了看解决了&#xff0c;我总结一下从头到尾排除问题&#xff0c;试到最后要是还解决不了你直接私信我&#xff0c;我给你看看…

vue3+uniapp

1.页面滚动 2.图片懒加载 3.安全区域 4.返回顶部&#xff0c;刷新页面 5.grid布局 place-self: center; 6.模糊效果 7.缩放 8.微信小程序联系客服 9.拨打电话 10.穿透 11.盒子宽度 12.一般文字以及盒子阴影 13.选中文字 14.顶部安全距离 15.onLoad周期函数在setup语法糖执行后…

微信小程序-案例:本地生活-首页(不使用网络数据请求)

一、 1.页面效果&#xff1a; 二、 1.新建项目并添加页面 在app.json文件中&#xff1a; "pages": ["pages/home/home","pages/message/message","pages/contact/contact"] 2.配置导航栏效果 在app.json文件中&#xff1a; &quo…

DVWA-XSS(DOM)

Low 后端没有代码&#xff0c;点击select按钮动作是前端的JS代码进行处理的 function addEventListeners() {var source_button document.getElementById ("source_button");if (source_button) {source_button.addEventListener("click", function() {v…

Doris Connector 结合 Flink CDC 实现 MySQL 分库分表

1. 概述 在实际业务系统中为了解决单表数据量大带来的各种问题&#xff0c;我们通常采用分库分表的方式对库表进行拆分&#xff0c;以达到提高系统的吞吐量。 但是这样给后面数据分析带来了麻烦&#xff0c;这个时候我们通常试将业务数据库的分库分表同步到数据仓库时&#x…

【杂谈】AIGC之ChatGPT-与智能对话机器人的奇妙对话之旅

与智能对话机器人的奇妙对话之旅 引言 在数字时代的浪潮中&#xff0c;ChatGPT如同一位智慧的旅伴&#xff0c;它不仅能够与我们畅谈古今&#xff0c;还能解答我们的疑惑&#xff0c;成为我们探索知识海洋的得力助手。今天&#xff0c;就让我们走进ChatGPT的世界&#xff0c;…

Capture One Pro 23:专业 Raw 图像处理的卓越之选

在当今的数字摄影时代&#xff0c;拥有一款强大的图像处理软件至关重要。而 Capture One Pro 23 for Mac/Win 无疑是其中的佼佼者&#xff0c;为摄影师和图像爱好者带来了前所未有的体验。 Capture One Pro 23 以其出色的 Raw 图像处理能力而闻名。它能够精准地解析和处理各种…