【转载】 《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</ ...
随机推荐
- Android复习(三)清单文件中的元素——> provider、receiver、service
<provider> 语法: <provider android:authorities="list" android:directBootAware=[&q ...
- VS2019插件更新慢的解决办法
VS2019更新巨慢,可以尝试通过以下几个方法解决: 1. 关闭IPV6 关闭IPV6:Win10怎么样禁用IPV6 如何关闭IPV6协议-百度经验 (baidu.com) 2. 选择最快的DNS 百 ...
- OKR 目标和关键成果
OKR(Objectives and Key Results)是目标与关键成果管理法,是一套明确和跟踪目标及其完成情况的管理工具和方法.1.OKR首先是沟通工具:团队中的每个人都要写OKR,所有这些O ...
- 为数据集而生的 SQL 控制台
随着数据集的使用量急剧增加,Hugging Face 社区已经变成了众多数据集默认存放的仓库.每月,海量数据集被上传到社区,这些数据集亟需有效的查询.过滤和发现. 每个月在 Hugging Face ...
- SQL Server 安装图解
此安装步骤适用于首次安装 一.SQL Server 安装 1.双击SQL Server 光盘映像文件,会出现如图所示界面 选择如下图所示的选项 2.输入产品密钥(这里演示密钥进行) 3.配置更新项,检 ...
- 3.14 深度剖析Linux硬链接和软链接,直击它们的本质!
建立硬链接和软链接非常简单,那这两种链接有什么区别?它们都有什么作用?这才是链接文件最不容易理解的地方,我们分别来讲讲. ln创建硬链接 我们再来建立一个硬链接文件,然后看看这两个文件的特点. [ro ...
- JAVA 两个时间 相差的 小时,天数,分钟
long nd = 1000 * 24 * 60 * 60; //每天毫秒数 long nh = 1000 * 60 * 60; //每小时毫秒数 long nm = 1000 * 60; //每分钟 ...
- delphi Image32 路径
用 Image32的理由之一,也是路径这块做得比delphi(FMX)自带的要好,skia中支持svg,但对路径处理功能不够强大.VCL只能使用第三方库. VCL如果要支持SVG,只有 Image32 ...
- 分析什么情况下回有大量的垃圾回收(GC)
在前端性能监控中,大量的垃圾回收(GC)通常是由以下原因导致的: 内存泄漏:当页面中的对象没有被正确地释放或引用计数错误时,会导致内存泄漏.当内存中的对象达到一定数量时,JavaScript 引擎会执 ...
- 谷歌chrome浏览器大量书签消失,怎么恢复历史?
作者:jdjdjdh链接:https://www.zhihu.com/question/400424237/answer/1604383205来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非 ...