前言:

最近在做Java开发对接微信公众平台之类的工作,在开发过程中遇到一个需求是定时任务这块的,但是普通的定时任务还远远不能满足;最后要实现的效果是每个任务都是不同的定时时间来执行而且是在前台页面上来控制这些任务的创建,取消,开启,暂停;就好比是向数据库添加一条记录(任务)那么在添加成功后这个任务就是进入定时执行状态了,每次执行的时间是由添加任务时前台页面选择的时间;

要实现的效果如下:

该项目的整体框架和环境选用的时SpringBoot,所以当时在网上看了大部分的boot整合Quartz的文章发现都存在bug和漏洞并且很麻烦和繁琐;通过在网上参考相关的文章加上之前积攒的知识,整合了一套简单并且实用的以上需求相关代码,可以参考。

pom:

<dependency>     <groupId>org.quartz-schedulergroupId>    <artifactId>quartzartifactId>    <version>2.2.1version>dependency>  

在项目的基础上需要添加上quartz的依赖包;(其他boot之类的依赖包就不一一说明了)

需要在启动类上开启定时任务

定时任务管理类:

import com.redleaves.wechat.api.core.Result;import com.redleaves.wechat.api.core.ResultGenerator;import com.redleaves.wechat.api.model.TTemplateMessage;import lombok.extern.slf4j.Slf4j;import org.quartz.*;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;/** * @author Mr.Gu * @date 2020/8/3 16:17 * @function :  定时任务的管理 **/@Slf4j@Servicepublic class SchedulerBuilder {    @Autowired    private Scheduler scheduler;    /**     * 新建job     * @param job     * @param clazz     * @return     */    public Result createJob(TTemplateMessage job, Class clazz) {        try {            if (!((clazz.newInstance()) instanceof Job)){                return ResultGenerator.genFailResult("必须实现job接口");            }            TriggerKey triggerKey = TriggerKey.triggerKey(job.getId().toString());            //获取trigger            CronTrigger trigger = null;            trigger = (CronTrigger) scheduler.getTrigger(triggerKey);            //不存在,创建一个            if (null == trigger) {                JobDetail jobDetail = JobBuilder.newJob(clazz)                        .withIdentity(job.getId().toString()).build();                jobDetail.getJobDataMap().put("scheduleJob", job);                //表达式调度构建器                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCorn());                //按新的cronExpression表达式构建一个新的trigger                trigger = TriggerBuilder.newTrigger().withIdentity(job.getId().toString()).withSchedule(scheduleBuilder).build();                scheduler.scheduleJob(jobDetail, trigger);                log.info("id为:{},推送名称为:{}的任务创建成功",job.getId(),job.getName());                return ResultGenerator.genSuccessResult();            }else{                return ResultGenerator.genFailResult("job已经存在,请检查名称是否重复");            }        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /**     * 立即执行job  是对已经存在的定时任务执行     * @param job     * @return     */    public Result executeJob(TTemplateMessage job) {        JobKey jobKey = JobKey.jobKey(job.getId().toString());        try {            scheduler.triggerJob(jobKey);            return ResultGenerator.genSuccessResult();        } catch (SchedulerException e) {            e.printStackTrace();            return ResultGenerator.genFailResult("操作失败");        }    }    /**     * 更新执行时间     * @param job     * @return     */    public Result updateJobCron(TTemplateMessage job) {        TriggerKey triggerKey = TriggerKey.triggerKey(job.getId().toString());        //获取trigger,即在spring配置文件中定义的 bean id="myTrigger"        CronTrigger trigger = null;        try {            trigger = (CronTrigger) scheduler.getTrigger(triggerKey);        } catch (SchedulerException e) {            e.printStackTrace();        }        //表达式调度构建器        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCorn());        //按新的cronExpression表达式重新构建trigger        trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();        //按新的trigger重新设置job执行        try {            scheduler.rescheduleJob(triggerKey, trigger);            return ResultGenerator.genSuccessResult();        } catch (SchedulerException e) {            e.printStackTrace();            return ResultGenerator.genFailResult("操作失败");        }    }    /**     * 暂停job运行     * @param job     * @return*/    public Result pauseJob(TTemplateMessage job) {        JobKey jobKey = JobKey.jobKey(job.getId().toString());        try {            scheduler.pauseJob(jobKey);            return ResultGenerator.genSuccessResult();        } catch (SchedulerException e) {            e.printStackTrace();            return ResultGenerator.genFailResult("操作失败");        }    }    /**     * 恢复job运行     * @param job     * @return*/    public Result resumeJob(TTemplateMessage job) {        JobKey jobKey = JobKey.jobKey(job.getId().toString());        try {            scheduler.resumeJob(jobKey);            return ResultGenerator.genSuccessResult();        } catch (SchedulerException e) {            e.printStackTrace();            return ResultGenerator.genFailResult("操作失败");        }    }    /* *     * 删除job信息     * @param job     * @return*/    public Result delJob(TTemplateMessage job) {        JobKey jobKey = JobKey.jobKey(job.getId().toString());        TriggerKey triggerKey = TriggerKey.triggerKey(job.getId().toString());        try {            scheduler.pauseTrigger(triggerKey);// 停止触发器            scheduler.unscheduleJob(triggerKey);// 移除触发器            scheduler.deleteJob(jobKey);//删除job            return ResultGenerator.genSuccessResult();        } catch (SchedulerException e) {            e.printStackTrace();            return ResultGenerator.genFailResult("操作失败");        }    }}

任务触发后具体的执行逻辑的实现:

import com.redleaves.wechat.api.dao.TTemplateMessageMapper;import com.redleaves.wechat.api.model.TTemplateMessage;import com.redleaves.wechat.api.service.SendTemplateService;import lombok.extern.slf4j.Slf4j;import org.quartz.*;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.context.support.SpringBeanAutowiringSupport;import javax.annotation.Resource;/** * @author Mr.Gu * @date 2020/8/3 13:36 * @function :  定时任务触发器 **/@Slf4jpublic class MyJob implements Job {    private JobDataMap jobmap = null;    /**     * 定时任务触发后任务的具体执行逻辑     * @param paramJobExecutionContext     * @throws JobExecutionException     */    @Override    public void execute(JobExecutionContext paramJobExecutionContext) throws JobExecutionException {        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);        TTemplateMessage tTemplateMessage = new TTemplateMessage();        this.jobmap = paramJobExecutionContext.getJobDetail().getJobDataMap();        tTemplateMessage = (TTemplateMessage) jobmap.get("scheduleJob");        log.info("开始执行任务id:{};推送名称为:{}",tTemplateMessage.getId(),tTemplateMessage.getName());        ----------------------任务的具体执行逻辑-----------------------------------    }}

在控制层中接收到请求后创建任务:

@RestController@RequestMapping("/template/message")public class TTemplateMessageController {    @Resource    private TTemplateMessageService tTemplateMessageService;    @Autowired    private SendTemplateService sendTemplateService;    @Resource    private SchedulerBuilder schedulerBuilder;    /**     * 新建模板消息推送     * @param templateMessageRequest     * @return     */    @PostMapping("/sendTemplateMessage")    public Result sendTemplateMessage(@RequestBody TTemplateMessage templateMessageRequest) {        try {          schedulerBuilder.createJob(templateMessageRequest,MyJob.class);            return ResultGenerator.genSuccessResult();        } catch (Exception e) {            e.printStackTrace();            return ResultGenerator.genFailResult("操作失败");        }    }  }

以上就可以实现前言中所说的动态管理;就分享了可以实现定时任务部分,我是先将任务保存到数据库中,之后任务在execute()触发后进行具体执行相关逻辑处理的时候再从数据库中查询到;以及其他的相关处理逻辑可以根据自己的业务来添加;

以上分享希望可以帮助到正在做定时任务的你,如果其他更好的意见和改善望指点;

如果这篇文章帮助到你了,分享出去让他帮助到更多挠头扣手的童鞋;

更多技术分享可以关注我的私人公众号,探索出Java更多的未知;

喜欢就分享、点赞、加关注哦!!

quartz 动态添加job_SpringBoot+Quartz实现动态管理定时任务相关推荐

  1. JS动态修改页面EasyUI datebox不生效、EasyUI动态添加Class、EasyUI动态渲染解析解决方案

    JS动态修改页面EasyUI datebox不生效.EasyUI动态添加Class.EasyUI动态渲染解析解决方案 参考文章: (1)JS动态修改页面EasyUI datebox不生效.EasyUI ...

  2. js动态添加样式和jQuery动态添加样式

    0.style方式添加样式 DOM对象.style.color = 'red'DOM对象.style.display = 'block/none' //让元素显示/隐藏 1.js动态添加样式 1.添加 ...

  3. php动态添加div,jq如何动态添加动态css样式

    jq动态添加动态css样式的方法:首先准备jquery库文件,并声明一个class样式:然后准备一个事件加载初始化的方法,并直接用匿名函数:接着addClass方法给div元素添加class:最后通过 ...

  4. android动态添加网格布局,android – 动态网格布局

    您可以动态生成GridView. GridView将根据您的需要包含ImageView和TextView.您必须使用自定义适配器.在它的getView方法中,填充ImageView和TextView. ...

  5. python 动态添加装饰器_python动态装饰器

    python的装饰器是静态的,也就是说你使用的装饰器一定是定义好的对象.在某些特殊的情况下,需要让动态使用装饰器. 警告 不要随便用这个办法,一点都不优雅,能够使用其他的方法规避动态调用装饰器就不要这 ...

  6. android relativelayout动态添加视图,android RelativeLayout 动态添加子View

    在很多时候xml里面的布局并不能满足我们的需求.这时候就需要用代码进行动态布局,前些天在对RelativeLayout 进行动态布局时遇到了些问题,现在解决了,分享下. 我现在在RelativeLay ...

  7. android动态添加数组中,Android动态数组

    我正在通过Android Pull Parser技术解析XML文件.首先,看看下面的XML文件: hello xyz abc def 考虑一下我正在解析上面的文件.现在,我的问题是我想为名称和地址创建 ...

  8. Elastic-Job:动态添加任务,支持动态分片

    多情只有春庭月,犹为离人照落花. 概述 因项目中使用到定时任务,且服务部署多实例,因此需要解决定时任务重复执行的问题.即在同一时间点,每一个定时任务只在一个节点上执行.常见的开源方案,如 elasti ...

  9. vue 动态添加click_vue,在模块中动态添加dom节点,并监听

    vue向数组中动态添加数据 vue中数据更新通过v-model实现,向数组中添加数据通过push()实现,向shortcuts数组中动态添加newShortcut对象中的title和action th ...

最新文章

  1. java nonewithrsa,如何使“MessageDigest SHA-1和Signature NONEwithRSA”等同于“Signature SHA1withRSA”...
  2. 高性能MySQL(第3版)
  3. [机器学习] 常用并行计算算子原理
  4. MyBatis中增删改操作
  5. go MySQL 多语句_八、MySQL经典查询语句-Go语言中文社区
  6. 【CodeForces - 255B】Code Parsing(思维,字符串)
  7. Python制作词云图根据蒙板图像确定形状和文字颜色
  8. 关于DiskFileUpload的杂谈
  9. 仿射变换再次秒杀2011山东理科高考压轴题(圆锥曲线)
  10. Word中部分内容出现乱码、不显示页码和目录
  11. 他捧红了王菲、张学友等近百个巨星,却甘心成为最普通的学佛人…
  12. spring boot 上传视频demo
  13. mysql 段错误 (core dumped)_CentOS yum 段错误 (core dumped)解决办法
  14. Excel中如何连续使用格式刷
  15. 转载过来的一些嵌入式资料
  16. 天然和合成石墨的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  17. 用Python做贪吃蛇小游戏
  18. draw.io 画流程图的神器
  19. 正n边形的魔法阵,判断该魔法阵消耗的魔力和产生的能量。
  20. 软件架构之 23种设计模式

热门文章

  1. 基于VMware vSphere 5.0的服务器虚拟化实践(9)
  2. hdpi、mdpi、ldpi图片规格
  3. 巴黎新式婴儿饼干,你敢吃吗?
  4. Excel应该这么玩——5、三种数据:Excel也是系统
  5. 投入千亿的菜鸟网络智慧物流做得怎么样?
  6. zabbix添加自定义监控项目-配置邮件告警-测试告警
  7. Linux 最新SO_REUSEPORT特性
  8. 学习redhat linux 6.1中文版笔记
  9. ASP.NET的include的用法
  10. 服务器物理内存高,服务器的物理内存高