【转载】 《SpringBoot2.0 实战》系列-集成Quartz定时任务(持久化到数据库)
https://blog.csdn.net/HXNLYW/article/details/95055601
一、增加依赖
我们使用的spring-boot-starter-quartz,所以不用显示指定版本号
<!--quartz相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
二、yml配置信息
spring:
# 数据库配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
datasource:
master:
url: xxx
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: xxx
quartz:
url: xxx
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: xxx
# quartz定时任务
quartz:
jdbc:
# 初始化Quartz表结构,项目第一次启动配置程always,然后改成never 否则已生成的job会被初始化掉
initialize-schema: never
#设置quartz任务的数据持久化方式,默认是内存方式
job-store-type: jdbc
properties:
org:
quartz:
scheduler:
instanceName: etlCleanScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_ #Quartz表前缀
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
#线程数 一个任务使用一个线程
threadCount: 100
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
自定生成表结构,需要配置如下信息:
spring.quartz.jdbc.initialize-schema: always
spring.quartz.job-store-type: jdbc
项目启动后生成的表信息

三、自定义数据源
其实到第二部配置就已经结束了,但是很多时候,我们希望quartz的数据源和项目的业务数据源是分离的,那我们需要再配置下数据源。
在启动类下增加以下代码:
/**
* 主数据源
* @return
*/
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.master")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
} /**
* 配置Quartz独立数据源的配置
*/
@Bean
@QuartzDataSource
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.quartz")
public DataSource quartzDataSource(){
return new DruidDataSource();
}
注意
一定要增加主数据源,并加上@primary注解,不然业务用的数据源会切换到quartz数据源
四、定时任务逻辑封装
QuartzService定时器操作业务类,需要增加数据源切换注解。
/**
* quartz逻辑
* @author gourd
*/
@Service
@DS("quartz")
public class QuartzServiceImpl implements QuartzService { @Autowired
private Scheduler scheduler; @PostConstruct
public void startScheduler() {
try {
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
} /**
* 增加一个job
*
* @param jobClass
* 任务实现类
* @param jobName
* 任务名称
* @param jobGroupName
* 任务组名
* @param jobTime
* 时间表达式 (这是每隔多少秒为一次任务)
* @param jobTimes
* 运行的次数 (<0:表示不限次数)
* @param jobData
* 参数
*/
@Override
public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,
int jobTimes, Map jobData) {
try {
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
.build();
// 设置job参数
if(jobData!= null && jobData.size()>0){
jobDetail.getJobDataMap().putAll(jobData);
}
// 使用simpleTrigger规则
Trigger trigger = null;
if (jobTimes < 0) {
trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
.startNow().build();
} else {
trigger = TriggerBuilder
.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder
.repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))
.startNow().build();
}
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
} /**
* 增加一个job
*
* @param jobClass
* 任务实现类
* @param jobName
* 任务名称(建议唯一)
* @param jobGroupName
* 任务组名
* @param jobTime
* 时间表达式 (如:0/5 * * * * ? )
* @param jobData
* 参数
*/
@Override
public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime, Map jobData) {
try {
// 创建jobDetail实例,绑定Job实现类
// 指明job的名称,所在组的名称,以及绑定job类
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
.build();
// 设置job参数
if(jobData!= null && jobData.size()>0){
jobDetail.getJobDataMap().putAll(jobData);
}
// 定义调度触发规则
// 使用cornTrigger规则
// 触发器key
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).startNow().build();
// 把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 修改 一个job的 时间表达式
*
* @param jobName
* @param jobGroupName
* @param jobTime
*/
@Override
public void updateJob(String jobName, String jobGroupName, String jobTime) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
// 重启触发器
scheduler.rescheduleJob(triggerKey, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
} /**
* 删除任务一个job
*
* @param jobName
* 任务名称
* @param jobGroupName
* 任务组名
*/
@Override
public void deleteJob(String jobName, String jobGroupName) {
try {
scheduler.deleteJob(new JobKey(jobName, jobGroupName));
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 暂停一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void pauseJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
} /**
* 恢复一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void resumeJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
} /**
* 立即执行一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void runAJobNow(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
} /**
* 获取所有计划中的任务列表
*
* @return
*/
@Override
public List<Map<String, Object>> queryAllJob() {
List<Map<String, Object>> jobList = null;
try {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
jobList = new ArrayList<Map<String, Object>>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
Map<String, Object> map = new HashMap<>();
map.put("jobName", jobKey.getName());
map.put("jobGroupName", jobKey.getGroup());
map.put("description", "触发器:" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
map.put("jobStatus", triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put("jobTime", cronExpression);
}
jobList.add(map);
}
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
} /**
* 获取所有正在运行的job
*
* @return
*/
@Override
public List<Map<String, Object>> queryRunJob() {
List<Map<String, Object>> jobList = null;
try {
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
jobList = new ArrayList<Map<String, Object>>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
Map<String, Object> map = new HashMap<String, Object>();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
map.put("jobName", jobKey.getName());
map.put("jobGroupName", jobKey.getGroup());
map.put("description", "触发器:" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
map.put("jobStatus", triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put("jobTime", cronExpression);
}
jobList.add(map);
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
} }
具体的Job类
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component; import java.util.Date; /**
* job触发时间
* @author gourd
*/
@Component
public class Job extends QuartzJobBean { @Override
protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
System.out.println(new Date() + " job执行");
// 获取参数
JobDataMap jobDataMap = arg0.getJobDetail().getJobDataMap();
// 业务逻辑 ...
} }
cron工具类,将date 转换成cron格式
import java.text.SimpleDateFormat;
import java.util.Date; public class QuartzCronDateUtils {
/***
* 日期转换cron表达式时间格式
* @param date
* @param dateFormat
* @return
*/
public static String formatDateByPattern(Date date,String dateFormat){
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
String formatTimeStr = null;
if (date != null) {
formatTimeStr = sdf.format(date);
}
return formatTimeStr;
}
/***
* convert Date to cron
* @param date:时间
* @return
*/
public static String getCron(Date date){
String dateFormat="ss mm HH dd MM ? yyyy";
return formatDateByPattern(date,dateFormat);
}
}
五、测试
@Autowired
private QuartzService quartzService; @PostMapping("/addjob")
@ApiOperation(value = "增加定时任务")
public void addJob() {
Map map = new HashMap(2);
map.put("id",1L);
quartzService.addJob(Job.class, "job", "test", "0/30 * * * * ?",map);
}
【转载】 《SpringBoot2.0 实战》系列-集成Quartz定时任务(持久化到数据库)的更多相关文章
- 【转】WF4.0实战系列索引
转自:http://www.cnblogs.com/zhuqil/archive/2010/07/05/wf4-in-action-index.html 此系列的工作流文件案例比较多点,实用性好. W ...
- Spring Boot 入门(九):集成Quartz定时任务
本片文章续<Spring Boot 入门(八):集成RabbitMQ消息队列>,关于Quartz定时任务请参考<Quartz的基本使用之入门(2.3.0版本)> spring ...
- maven项目集成Quartz定时任务框架,实现批处理功能
一.Quartz简介 主要做定时任务,即:在指定时间点或时间段,执行某项任务,可设置执行次数.时间间隔等. 二.Springcloud简介 对比传统的.庞大的.复杂的.以ssm或ssh为框架的web项 ...
- SpringBoot2.0 基础案例(04):定时任务和异步任务的使用方式
一.定时任务 1.基本概念 按照指定时间执行的程序. 2.使用场景 数据分析 数据清理 系统服务监控 二.同步和异步 1.基本概念 同步调用 程序按照代码顺序依次执行,每一行程序都必须等待上一行程序执 ...
- (2)Spring集成Quartz定时任务框架介绍和Cron表达式详解
在JavaEE系统中,我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等.我们可以使用java.util.Timer结合java.util.TimerTask来完成这项工作,但 ...
- Spring集成Quartz定时任务框架介绍和Cron表达式详解
原文地址:http://www.cnblogs.com/obullxl/archive/2011/07/10/spring-quartz-cron-integration.html 在JavaEE系统 ...
- Spring_Spring集成Quartz定时任务框架介绍和Cron表达式详解
在JavaEE系统中,我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等.我们可以使用java.util.Timer结合java.util.TimerTask来完成这项工作,但 ...
- Spring集成Quartz定时任务框架介绍
在JavaEE系统中,我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等.我们可以使用java.util.Timer结合java.util.TimerTask来完成这项工作,但 ...
- spring boot 集成 quartz 定时任务
spring boot: @EnableScheduling开启计划任务支持,@Scheduled计划任务声明 1.pom.xml 引入依赖 <dependency> <groupI ...
- springboot集成quartz定时任务课动态执行
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</ ...
随机推荐
- Java日期时间API系列33-----Jdk8中java.time包中的新的日期时间API类应用,格式化常用模板大全,新增Excel常用格式。
从Java日期时间API系列10-----Jdk8中java.time包中的新的日期时间API类的DateTimeFormatter中可以知道常用字符有超过20几种,各种组合结果非常多.但常用的组合就 ...
- vue合计行添加点击事件
项目开发中做统计报表的时候,用到了合计功能.这个直接添加el-table已经封装好的show-summary属性就可以,但是如何给合计单元格添加点击事件呢?@cell-click="cell ...
- 云原生周刊:K8sGPT 加入 CNCF | 2024.1.8
开源项目推荐 VolSync VolSync 使用 rsync 或 rclone 在集群之间异步复制 Kubernetes 持久卷.它还支持通过 Restic 创建持久卷的备份. KubeClarit ...
- 蜘点云原生之 KubeSphere 落地实践过程
作者:池晓东,蜘点商业网络服务有限公司技术总监,从事软件开发设计 10 多年,喜欢研究各类新技术,分享技术. 来源:本文由 11 月 25 日广州站 meetup 中讲师池晓东整理,整理于该活动中池老 ...
- 开启 Calico eBPF 数据平面实践
简介 Calico 从 v3.13 开始,集成了 eBPF 数据平面. 关于什么是 eBPF, 以及 Calico 为什么引入了 eBPF , 并不是本篇文章的重点,感兴趣的朋友可以自行阅读相关文档. ...
- php运行redis测试
在今天将官方的redis教程看完之后,想自己来一个测试. 按照官方给出的代码: 1 <?php 2 //连接本地的 Redis 服务 3 $redis = new Redis(); 4 $red ...
- 一文彻底弄懂MySQL的MVCC多版本控制器
InnoDB 的 MVCC(Multi-Version Concurrency Control,多版本并发控制) 是 MySQL 实现高并发事务处理的一种机制.通过 MVCC,InnoDB 可以在高并 ...
- VScode如何设置浅色侧栏
原文地址:https://blog.csdn.net/KaiSarH/article/details/113241334 vscode主题设置成了浅色,但是侧边栏仍然是灰色,非常讨厌. 在设置中对&q ...
- RAC环境中某数据文件(非system表空间)创建在本地,不停机迁移到ASM磁盘中
Datafiles are mistakenly built into the local file system for processing in the RAC environment The ...
- Invalid default value for prop "value": Props with type Object/Array must use a factory function to return the default value.
Invalid default value for prop "value": Props with type Object/Array must use a factory fu ...