使用:

个人博客项目,定时刷新帖子排名用到了定时任务,在这里记录下来SpringBoot整合Quartz的基本使用,记录的同时也希望能帮助到大家。

1.什么是Quartz

官方介绍:

Quartz是一个功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中,从最小的独立应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的调度,用于执行数以万计、数百甚至数万个作业;其任务被定义为标准Java组件的作业,可以执行几乎任何您可以编程它们执行的任务。Quartz调度程序包含许多企业级特性,例如对JTA事务和集群的支持。

Quartz有三要素:

  • Scheduler:任务调度器,所有的任务都是从这里开始。
  • Trigger:触发器,主要制定定时任务执行的规则。
  • JobDetail & Job : 加载定时逻辑实现的类,定义任务具体执行逻辑。

2.使用

这里介绍的是springboot2.0及以上版本和spring2.0以下版本的使用,下面先介绍2.0及以上版本,相对来说简单很多

2.1springboot2.0及以上版本进行持久化

Meven工程引入quartz的jar包:

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

编写quartz的相关配置(application.properties):

# QuartzProperties
spring.quartz.job-store-type=jdbc
spring.quartz.scheduler-name=communityScheduler
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.isClustered=true
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
spring.quartz.properties.org.quartz.threadPool.threadCount=5# 要用到持久化,需要连接数据库,数据库配置 。。。大同小异这里就不贴出来了

由于要持久化quartz(方便集器及对任务进行管理,停止修改等),这里还需要在数据库(mysql)中创建11张固定的表,官方提供了相关的sql文件,下载对应版本quartz,解压打开docs/dbTables里面有对应数据库的建表语句,建表语句可以参考这篇博客。

  • qrtz_blob_triggers : 以Blob 类型存储的触发器。
  • qrtz_calendars:存放日历信息, quartz可配置一个日历来指定一个时间范围。
  • qrtz_cron_triggers:存放cron类型的触发器。
  • qrtz_fired_triggers:存放已触发的触发器。
  • qrtz_job_details:存放一个jobDetail信息。
  • qrtz_job_listeners:job监听器。
  • qrtz_locks: 存储程序的悲观锁的信息(假如使用了悲观锁)。
  • qrtz_paused_trigger_graps:存放暂停掉的触发器。
  • qrtz_scheduler_state:调度器状态。
  • qrtz_simple_triggers:简单触发器的信息。
  • qrtz_trigger_listeners:触发器监听器。
  • qrtz_triggers:触发器的基本信息。

这里创建job实现类TestJob,来执行相关逻辑:

public class TestJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {//相关逻辑代码。。。System.out.println("Quartz定时任务执行了!!!");}
}

创建配置类QuartzConfigm,用于配置Trigger与JobDetail:

// 配置JobDetail 主要加载定时逻辑实现的类@Beanpublic JobDetailFactoryBean TestJobDetail() {JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();factoryBean.setJobClass(TestJob.class);//任务名字factoryBean.setName("TestJob");//组名factoryBean.setGroup("TestJobGroup");factoryBean.setDurability(true);factoryBean.setRequestsRecovery(true);return factoryBean;}// 配置Trigger(SimpleTriggerFactoryBean, CronTriggerFactoryBean) 主要制定定时任务执行的规则@Beanpublic SimpleTriggerFactoryBean alphaTrigger(JobDetail TestJobDetail) {SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();factoryBean.setJobDetail(TestJobDetail);factoryBean.setName("TestTrigger");factoryBean.setGroup("TestTriggerGroup");factoryBean.setRepeatInterval(3000);factoryBean.setJobDataMap(new JobDataMap());return factoryBean;}

执行SpringBoot启动类,启动。。

2.1.1动态对job定时任务实现增删改查

下面已经封装好了:

    /*** 删除job** @param triggerName  触发器名称* @param triggerGroup 触发器分组* @param jobName      任务名称* @param jobGroup     任务分组* @throws SchedulerException*/public void deleteJob(String triggerName, String triggerGroup, String jobName, String jobGroup) throws SchedulerException {TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);scheduler.pauseTrigger(triggerKey);scheduler.unscheduleJob(triggerKey);JobKey jobKey = JobKey.jobKey(jobName, jobGroup);scheduler.deleteJob(jobKey);}/*** 修改定时任务** @param oldTriggerKey 需要修改的TriggerKey 也就是唯一标识* @param cron          新的cron表达式*/public void updateJob(TriggerKey oldTriggerKey, String cron) {CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(oldTriggerKey).withSchedule(scheduleBuilder).build();try {scheduler.rescheduleJob(oldTriggerKey, cronTrigger);} catch (SchedulerException e) {e.printStackTrace();}}/*** 新增job任务** @param jobName          job名称* @param jobGroupName     job分组名称* @param triggerName      触发器名称* @param triggerGroupName 触发器分组名称* @param jobClass         需要执行的job.class* @param cron             cron 表达式* @throws SchedulerException*/public void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class jobClass, String cron) throws SchedulerException {CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(cronScheduleBuilder).build();scheduler.scheduleJob(jobDetail, trigger);}

2.2springboot2.0以下版本进行持久化

maven工程引入jar包:

<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.3.0</version></dependency><!--定时任务需要依赖context模块--><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency>

编写quartz的相关配置,这里单独写个配置文件,不放在application中了(quartz.properties):

#使用自己的配置文件
org.quartz.jobStore.useProperties:trueorg.quartz.scheduler.instanceName: DefaultQuartzScheduler
#如果使用集群,instanceId必须唯一,设置成AUTO
org.quartz.scheduler.instanceId = AUTOorg.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true#存储方式使用JobStoreTX,也就是数据库
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#是否使用集群(如果项目只部署到 一台服务器,就不用了)
org.quartz.jobStore.isClustered = false
org.quartz.jobStore.clusterCheckinInterval=20000
org.quartz.jobStore.tablePrefix = qrtz_
org.quartz.jobStore.dataSource = myDS#配置数据源
#数据库中quartz表的表名前缀
org.quartz.dataSource.myDS.driver=com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=utf-8&useSSL=false
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
org.quartz.dataSource.myDS.maxConnections = 5

也需要在数据库中引入相应的quartz数据库表,和上面操作一样,这里就不重复介绍了。

核心QuartzConfig类:

import org.quartz.Scheduler;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.*;@Configuration
public class QuartzConfig {@Autowiredprivate JobFactory jobFactory;@Beanpublic SchedulerFactoryBean schedulerFactoryBean() {SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();schedulerFactoryBean.setJobFactory(jobFactory);// 启动时更新己存在的JobschedulerFactoryBean.setOverwriteExistingJobs(true);//延长启动schedulerFactoryBean.setStartupDelay(1);//设置加载的配置文件schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));return schedulerFactoryBean;}@Beanpublic Scheduler scheduler() {return schedulerFactoryBean().getScheduler();}
}

MyJobFactory类:

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;@Component
public class MyJobFactory extends AdaptableJobFactory {@Autowiredprivate AutowireCapableBeanFactory capableBeanFactory;@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {// 调用父类的方法Object jobInstance = super.createJobInstance(bundle);// 进行注入capableBeanFactory.autowireBean(jobInstance);return jobInstance;}
}

测试job:

public class TestJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {//相关逻辑代码。。。JobDataMap dataMap = jobExecutionContext.getJobDetail().getJobDataMap();String data= Long.valueOf(dataMap.getString("data"));System.out.println("Quartz定时任务执行了!!!接收到值:"+data);}
}

编写测试用例:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@Rollback
public class ColumnGenerator {@Testpublic void test() throws InterruptedException {String cron = "0/8 * * * * ?";QuartzUtils.addJob("31","group","31","trigger",TestJob.class,cron,"data","成功");Thread.sleep(90000000);}
}

执行,大功告成。

2.2.1job动态增删改查

这里也提供写好的工具类,可以直接使用:

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;import java.text.ParseException;public class QuartzUtils {private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();/*** @Description: 添加一个定时任务** @param jobName 任务名* @param jobGroupName  任务组名* @param triggerName 触发器名* @param triggerGroupName 触发器组名* @param jobClass  任务* @param cron   时间设置,参考quartz说明文档*/@SuppressWarnings({ "unchecked", "rawtypes" })public static void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class jobClass, String cron,String jobKey,String jobValue) {try {Scheduler sched = schedulerFactory.getScheduler();// 任务名,任务组,任务执行类JobDetail jobDetail= JobBuilder.newJob(jobClass).usingJobData(jobKey, jobValue).withIdentity(jobName, jobGroupName).build();// 触发器TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();// 触发器名,触发器组triggerBuilder.withIdentity(triggerName, triggerGroupName);triggerBuilder.startNow();// 触发器时间设定triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));// 创建Trigger对象CronTrigger trigger = (CronTrigger) triggerBuilder.build();// 调度容器设置JobDetail和Triggersched.scheduleJob(jobDetail, trigger);// 启动if (!sched.isShutdown()) {sched.start();}} catch (Exception e) {throw new RuntimeException(e);}}/*** @Description: 修改一个任务的触发时间** @param triggerName 触发器名* @param triggerGroupName 触发器组名* @param cron   时间设置,参考quartz说明文档*/public static void modifyJobTime(String triggerName, String triggerGroupName, String cron) {try {Scheduler sched = schedulerFactory.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);if (trigger == null) {return;}String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(cron)) {/** 方式一 :调用 rescheduleJob 开始 */// 触发器TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();// 触发器名,触发器组triggerBuilder.withIdentity(triggerName, triggerGroupName);triggerBuilder.startNow();// 触发器时间设定triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));// 创建Trigger对象trigger = (CronTrigger) triggerBuilder.build();// 方式一 :修改一个任务的触发时间sched.rescheduleJob(triggerKey, trigger);/** 方式一 :调用 rescheduleJob 结束 *//** 方式二:先删除,然后在创建一个新的Job  *///JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));//Class<? extends Job> jobClass = jobDetail.getJobClass();//removeJob(jobName, jobGroupName, triggerName, triggerGroupName);//addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);/** 方式二 :先删除,然后在创建一个新的Job */}} catch (Exception e) {throw new RuntimeException(e);}}/*** @Description: 移除一个任务** @param jobName* @param jobGroupName* @param triggerName* @param triggerGroupName*/public static void removeJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName) {try {Scheduler sched = schedulerFactory.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);sched.pauseTrigger(triggerKey);// 停止触发器sched.unscheduleJob(triggerKey);// 移除触发器sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务} catch (Exception e) {throw new RuntimeException(e);}}/*** @Description:启动所有定时任务*/public static void startJobs() {try {Scheduler sched = schedulerFactory.getScheduler();sched.start();} catch (Exception e) {throw new RuntimeException(e);}}/*** @Description:关闭所有定时任务*/public static void shutdownJobs() {try {Scheduler sched = schedulerFactory.getScheduler();if (!sched.isShutdown()) {sched.shutdown();}} catch (Exception e) {throw new RuntimeException(e);}}
}

SpringBoot整合Quartz执行持久化定时任务相关推荐

  1. springboot整合quartz,实现数据库方式执行定时任务

    springboot整合quartz,实现数据库方式执行定时任务.把定时任务信息存进数据库,项目启动后自动执行定时任务. 1.引入依赖包: <dependency><groupId& ...

  2. Spring Boot定时任务-SpringBoot整合Quartz

    如何通过SpringBoot整合Quartz框架,我们首先去创建一个项目,接下来我们需要在pom文件里添加坐标,我们在使用SpringBoot整合Quartz的时候,需要添加哪些坐标呢,我们来看一下, ...

  3. Java-Quartz实现定时任务(SpringBoot整合quartz)

    Quartz简介 Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单 ...

  4. SpringBoot整合Quartz之动态控制任务(暂停,启动,修改执行时间)

    SpringBoot整合 Quartz 篇请移步 https://blog.csdn.net/yali_aini/article/details/85287074 此篇文章讲述如何动态控制 Quart ...

  5. Springboot整合Quartz任务框架

      分享一篇关于Springboot整合Quartz任务框架在实际开发中的使用,基于SpringBoot2.0+Mybatis+Oracle开发 1. 导入jar包 <!-- 定时任务 --&g ...

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

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

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

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

  8. SpringBoot整合Quartz==适用于单任务多任务

    上一篇文章简单的介绍了一下Quartz的控制台运行,有兴趣的可以看看https://blog.csdn.net/yali_aini/article/details/85273209 这里我会介绍一下 ...

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

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

最新文章

  1. 为什么在C中需要使用volatile?
  2. linux 解压 tar.gz 报错 gzip: stdin: not in gzip format
  3. 旷视:深度学习框架开源
  4. Vmware虚拟机网络及IP配置
  5. python 输入华氏温度f_如何用 python编写华氏摄氏度的相互转换?
  6. 你是不是 可替代的Linux运维工程师?
  7. a大于10小于15C语言,计算机基础复习模拟试卷
  8. go语言环境搭建及vim高亮设置
  9. C# WPF仿360安全卫士11
  10. 人民币对澳元汇率的大数据分析与预测
  11. php删除文件找回,在文件管理删除的视频怎么找回?
  12. 高德api只显示省级地图
  13. 用QQ邮箱接收网易163企业邮箱的邮件
  14. 大话西游2同一个账号同一个服务器,大话西游2:服务器合并你是否支持?老玩家告诉你合服后的影响!...
  15. 7-34 任务调度的合理性(25 分)
  16. 面试官:SPA(单页应用)首屏加载速度慢怎么解决?
  17. 最长递增子序列的O(NlogN)算法
  18. Unity 3D光源-Point Light点光源详解/灯泡、模拟灯光效果教程
  19. Git - Gitee码云 使用手册
  20. UCOSIII 任务管理(中)

热门文章

  1. unity全栈开发是什么意思_前端所谓的全栈和大前端有什么区别?
  2. 微博营销事件背后的真与假
  3. php类型 fcgi,Apache使用fcgi方式与PHP结合
  4. QQ的Tencent://Message/协议
  5. 【去雨】Self-Learning Video Rain Streak Removal: When Cyclic Consistency Meets Temporal Correspondence
  6. 马宁教你如何通过软件编译实现嵌入式开发
  7. MySQL45讲学习笔记(1)
  8. 如何分辨一个程序员是不是水货?
  9. VMware-ESXi_8.0U1_21495797_DIYNAS网卡驱动整合版.iso
  10. day4-分支和循环