点击上方蓝色“方志朋”,选择“设为星标”

回复“666”获取独家整理的学习资料!


首先说下这次主题,动态配置。没接触过定时任务的同学可以先看下此篇:

https://www.cnblogs.com/laoyeye/p/6530791.html

定时任务实现方式千人千种,不过基础的无外乎 1、JDK 的Timer类 2、Quartz 3、SpringTask  。生产上三种方式我都有使用过。但是使用过程中用的最多的便是xml配置的方式,这种方式最简单,无代码侵入,也比较好理解。

但是却有个致命的缺点,比如你要改某个任务的触发时间,亦或是你要新增一个任务,暂停一个任务。怎么做?

停应用!改XML配置!重新启动!

是不是很致命。最近重新研究了下Quartz的配置,实现了不停机添加、暂停、删除、立即触发任务的方法,在本篇分享出来,其实也不算是完全的研究,在上家公司已经有大佬实现了,这次是也是基于大佬的理解重新实现下。

管理界面:

效果图:实在不知道该跑什么了,每隔十秒打一段话吧

maven依赖

使用spring boot做框架支持

<!-- quartz -->
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.1</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId>
</dependency>

数据表

CREATE TABLE `sys_task` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`job_name` varchar(255) DEFAULT NULL COMMENT '任务名',`description` varchar(255) DEFAULT NULL COMMENT '任务描述',`cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron表达式',`bean_class` varchar(255) DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名',`job_status` varchar(255) DEFAULT NULL COMMENT '任务状态',`job_group` varchar(255) DEFAULT NULL COMMENT '任务分组',`create_user` varchar(64) DEFAULT NULL COMMENT '创建者',`create_time` datetime DEFAULT NULL COMMENT '创建时间',`update_user` varchar(64) DEFAULT NULL COMMENT '更新者',`update_time` datetime DEFAULT NULL COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

实现步骤

① 启动项目,启动task监听

② 读取数据库,将开启的任务job和trigger加载到scheduler调度器

③ 根据任务调度运行job类

④ 每次运行利用AdaptableJobFactory实例化job类,以便注入要运行的service

听着是不是很简单,但却还是一头雾水,且听我慢慢道来~~

代码逻辑

第一步:启动项目,加载监听

Quartz配置

Springboot的配置方法,常规Spring项目可以在xml中配置

@Configuration
public class QuartzConfigration {@Autowiredprivate JobFactory jobFactory;@Beanpublic SchedulerFactoryBean schedulerFactoryBean() {SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();try {schedulerFactoryBean.setOverwriteExistingJobs(true);schedulerFactoryBean.setQuartzProperties(quartzProperties());schedulerFactoryBean.setJobFactory(jobFactory);} catch (Exception e) {e.printStackTrace();}return schedulerFactoryBean;}// 指定quartz.properties,可在配置文件中配置相关属性@Beanpublic Properties quartzProperties() throws IOException {PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties"));propertiesFactoryBean.afterPropertiesSet();return propertiesFactoryBean.getObject();}// 创建schedule@Bean(name = "scheduler")public Scheduler scheduler() {return schedulerFactoryBean().getScheduler();}
}

监听器

@Component
@Order(value = 1)
public class ScheduleJobInitListener implements CommandLineRunner {@AutowiredTaskService scheduleJobService;@Overridepublic void run(String... arg0) throws Exception {try {scheduleJobService.initSchedule();} catch (Exception e) {e.printStackTrace();}}}

CommandLineRunner类似Spring框架的ApplicationListener监听器。官方的解释是:

Interface used to indicate that a bean should run when it is contained within a SpringApplication. Multiple CommandLineRunner beans can be defined within the same application context and can be ordered using the Ordered interface or Order @Order annotation.
接口被用作将其加入spring容器中时执行其run方法。多个CommandLineRunner可以被同时执行在同一个spring上下文中并且执行顺序是以order注解的参数顺序一致。

第二步:读取数据库,加载scheduler调度器

job方法

@Overridepublic void initSchedule() throws SchedulerException {// 这里获取任务信息数据List<TaskDO> jobList = taskMapper.list();for (TaskDO task : jobList) {if (JobStatusEnum.RUNNING.getCode().equals(task.getJobStatus())) {quartzManager.addJob(task);}}}

添加任务到Quartz调度器

/*** 添加任务*/@SuppressWarnings("unchecked")public void addJob(TaskDO task) {try {// 创建jobDetail实例,绑定Job实现类// 指明job的名称,所在组的名称,以及绑定job类Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance().getClass());JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(task.getJobName(), task.getJobGroup())// 任务名称和组构成任务key.build();// 定义调度触发规则// 使用cornTrigger规则Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup())// 触发器key.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND)).withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).startNow().build();// 把作业和触发器注册到任务调度中scheduler.scheduleJob(jobDetail, trigger);// 启动if (!scheduler.isShutdown()) {scheduler.start();}} catch (Exception e) {e.printStackTrace();}}

Scheduler作为Quartz的核心调度器,有将近50多个API接口,包括任务的添加,暂停,恢复,删除等一系列的API,这里仅介绍一些常用的,想要了解更多可以稍后看下彩蛋部分。

1、start()方法:只有调用start()方法后,Scheduler线程才开始启动触发器trigger,运行job

2、pauseJob(JobKey jobKey) :根据指定的JobDetail key暂停job。

3、resumeJob(JobKey jobKey) :根据指定的key恢复一个job。

4、deleteJob(JobKey jobKey) :删除一个job

5、triggerJob(JobKey jobKey) :触发一个JobDetail(现在执行)。

6、rescheduleJob(TriggerKey triggerKey, Trigger newTrigger):

用给定的键删除触发器,并存储新的触发器,它必须与同一个作业相关联(新触发器必须具有指定的作业名和组)-然而,新触发器不必具有与旧触发器相同的名称。

第三步:根据任务调度运行job类

其实这一步是不需要我们编写的,在我们将正确的JobDetail 和 Trigger 表达式加载到任务调度后,调度器会自动触发任务的执行

第四步:实例化job类,注入要运行的service

工厂类

@Component
public class JobFactory extends AdaptableJobFactory {//这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.//为什么需要这个类呢,在我写的这个demo中,大家可以将此类删掉,发现程序也可以正确运行,可是我为什么还是加上呢。//大家可以看下我们的任务类,大家可以看到Job对象的实例化过程是在Quartz中进行的,这时候我们将spring的东西注入进来,肯定是行不通的,所以需要这个类@Autowiredprivate AutowireCapableBeanFactory capableBeanFactory;@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {//调用父类的方法Object jobInstance = super.createJobInstance(bundle);//进行注入capableBeanFactory.autowireBean(jobInstance);return jobInstance;}
}

任务类

@DisallowConcurrentExecution //作业不并发
@Component
public class HelloWorldJob implements Job{@Overridepublic void execute(JobExecutionContext arg0) throws JobExecutionException {System.out.println("欢迎使用yyblog,这是一个定时任务 --小卖铺的老爷爷!"+ DateUtils.fullTime(new Date()));}}

好了,大功告成,一个简单的动态配置的定时任务已经完成。是不是so easy,下面我们再来简单实现下其他的几种常用的api吧。

暂停一个job

public void pauseJob(TaskDO task) throws SchedulerException {JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());scheduler.pauseJob(jobKey);}

恢复一个job

public void resumeJob(TaskDO task) throws SchedulerException {JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());scheduler.resumeJob(jobKey);}

删除一个job

public void deleteJob(TaskDO task) throws SchedulerException {JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());scheduler.deleteJob(jobKey);}

立即触发job

public void runJobNow(TaskDO task) throws SchedulerException {JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());scheduler.triggerJob(jobKey);}

更新job表达式

public void updateJobCron(TaskDO task) throws SchedulerException {TriggerKey triggerKey = TriggerKey.triggerKey(task.getJobName(), task.getJobGroup());CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExpression());trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();scheduler.rescheduleJob(triggerKey, trigger);}

好了,正文部分基本上就这些,不多废话了,本文没有太多的讲解原理,只是简单的应用,水平不够还望大家见谅。

看了上面的效果图是不是还是有种看的见摸不着的感觉,老爷爷这里也做了个线上的实例供大家体验~有兴趣的同学可以亲自试验一下。

实例地址:http://www.laoyeye.net/management/index  账号/密码:test/123456  菜单:系统设置/计划任务

当然了还有最重要的源码和API文档我也不会忘的。

源码地址:https://github.com/allanzhuo/yyblog

Quartz文档地址:https://github.com/allanzhuo/yyblog/tree/master/doc

最后的最后,看都看了,码字不易,顺手点个赞白~^_^

作者:小卖铺的老爷爷

链接:cnblogs.com/laoyeye/p/9352002.html

热门内容:
  • 因为BitMap,白白搭进去8台服务器...

  • Spring Boot 无侵入式 实现API接口统一JSON格式返回

  • 推荐一款免费的数据库管理工具,比Navicat还要好用,功能还很强大

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)

Spring Boot 整合 Quartz 实现 Java 定时任务的动态配置相关推荐

  1. Springboot2 Quartz实现JAVA定时任务的动态配置

    动态配置Quartz.没接触过定时任务的同学可以先看下此篇:JAVA定时任务实现的几种方式 文章目录 一.需求背景 1. 问题现象 2. 问题分析 3. 解决方案 二.需求背景 2.1. maven依 ...

  2. Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅)

    Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅) 1. 配置环境 在SpringBoot2.0版本以后,原来使用的jedis被替换成为了let ...

  3. Spring 3整合Quartz 2实现定时任务--转

    常规整合 http://www.meiriyouke.net/?p=82 最近工作中需要用到定时任务的功能,虽然Spring3也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之 ...

  4. Spring 3整合Quartz 2实现定时任务(转)

    http://www.meiriyouke.net/?p=82 最近工作中需要用到定时任务的功能,虽然Spring3也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之后,决定整 ...

  5. spring boot整合Quartz 在Job类中注入其他对象报空指针异常java.lang.NullPointerException at com.sxt.quartz.QuartzDemo.e

    情况在Job 类中注入RedisTemplate 报空指针异常 原因:我们使用JobDetailFactoryBean 帮我们创建对象 实际上调用的是AdaptableJobFactory 下的这个方 ...

  6. quartz 两个java_spring boot整合quartz实现多个定时任务的方法

    最近收到了很多封邮件,都是想知道spring boot整合quartz如何实现多个定时任务的,由于本人生产上并没有使用到多个定时任务,这里给个实现的思路. 1.新建两个定时任务,如下: public ...

  7. Spring Boot 教程(三): Spring Boot 整合Mybatis

    教程简介 本项目内容为Spring Boot教程样例.目的是通过学习本系列教程,读者可以从0到1掌握spring boot的知识,并且可以运用到项目中.如您觉得该项目对您有用,欢迎点击收藏和点赞按钮, ...

  8. 使用Spring整合Quartz轻松完成定时任务

    一.背景 上次我们介绍了如何使用Spring Task进行完成定时任务的编写,这次我们使用Spring整合Quartz的方式来再一次实现定时任务的开发,以下奉上开发步骤及注意事项等. 二.开发环境及必 ...

  9. java 模板引擎_极简 Spring Boot 整合 Thymeleaf 页面模板

    点击"牧码小子"关注,和众多大牛一起成长! 关注后,后台回复 java ,领取松哥为你精心准备的技术干货! 虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在 ...

最新文章

  1. 机智云官网用到的库-grid.css我解析
  2. 看下这段程序 ^_^
  3. SQL语句order by两个字段同时排序
  4. 笔记-信息系统安全管理-网络安全工具
  5. 【数据结构总结】第七章 查找
  6. Dubbo xml配置 和注解配置 写法
  7. *args, **kwargs的用法
  8. 蓝桥杯(java)基础练习 龟兔赛跑
  9. DBUtils学习笔记
  10. 在php 添加时间,在PHP中添加时间
  11. 如何修改iTunes的iPhone备份路径?
  12. 文本挖掘基本流程概述 分词和TF-IDF值计算方法介绍
  13. 宏电4g路由器流量卡怎么设置_宏电4g无线路由器设置_4g路由器怎么设置网口
  14. 《Linux运维总结:SVN提示Node remains in conflict解决办法》
  15. opencv-3.0.0-beta和opencv2版本的区别
  16. 梁念坚:“云计算”福音
  17. BIT_陆小果的一元多项式
  18. Latex如何写参考文献及修改顺序
  19. MapReduce程序中的万能输入FileInputFormat.addInputPaths
  20. EIGRP协议工作过程与配置详解

热门文章

  1. Spring注解 开发
  2. 使用 Azure CLI 管理 Azure 虚拟网络和 Linux 虚拟机
  3. tensorflow1
  4. 呼叫中心的服务水平管理
  5. CSipSimple 工程分析 1
  6. 算法基础知识科普:8大搜索算法之红黑树(下)
  7. Sobel 边缘实现
  8. 百度飞桨成为北京市首个AI产业方向创新应用平台
  9. 我帮公司财务写了个“群发工资条”的Python脚本
  10. 好莱坞科幻新片《b》,钦定 AI 机器人出演女主角!