SpringBoot 1.5.x 集成 Quartz 任务调度框架
Quartz 有分 内存方式 和 数据库方式
内存方式任务信息保存在内存中, 停机会丢失, 需手动重新执行, 数据库方式: 任务信息保存在数据库中, 重点是支持集群.
内存方式 RAMJobStore 和 数据库方式 JobStoreTX, RAMJobStore 适合单机, 不支持集群, JobStoreTX 支持集群.
下面介绍的就是 JobStoreTX 数据库方式.
1. 添加主要的相关依赖, 其他依赖这里就不说了
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
2. quartz 的数据库表目前有 11 个, 可以下载官方包, 在官方包中可以找到建表语句, 对应不同的数据库有相应的sql语句.
配置文件 quartz.properties
org.quartz.scheduler.instanceName=DefaultQuartzScheduler
org.quartz.scheduler.instanceid=AUTO
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=20
org.quartz.threadPool.threadPriority=5
org.quartz.jobStore.misfireThreshold=2000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=20000
org.quartz.dataSource.myDS.driver=org.mariadb.jdbc.Driver
org.quartz.dataSource.myDS.URL=jdbc:mariadb://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
#org.quartz.dataSource.myDS.driver=com.mysql.jdbc.Driver
#org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
org.quartz.dataSource.myDS.user=root
org.quartz.dataSource.myDS.password=root
org.quartz.dataSource.myDS.maxConnections=5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
3. JobFactory
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
@Configuration
public class JobFactory extends SpringBeanJobFactory {
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object createJobInstance = super.createJobInstance(bundle);
autowireCapableBeanFactory.autowireBean(createJobInstance);
return createJobInstance;
}
}
4. QuartzConfig
import java.io.IOException;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfig {
@Autowired
private JobFactory jobFactory;
// @Autowired
// private DataSource dataSource; // 如果使用application.properties中的数据源可以用这种方式
@Bean
public SchedulerFactoryBean myScheduler() throws IOException {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
// schedulerFactoryBean.setDataSource(dataSource); // 使用 application.properties 中的数据源
schedulerFactoryBean.setOverwriteExistingJobs(true);
schedulerFactoryBean.setJobFactory(jobFactory);
schedulerFactoryBean.setQuartzProperties(quartzProperties()); // 使用 quartz.properties 中的数据源
schedulerFactoryBean.setSchedulerName("myScheduler");
schedulerFactoryBean.setStartupDelay(2);// 延迟两秒启动
schedulerFactoryBean.setAutoStartup(true);
return schedulerFactoryBean;
}
@Bean
public SchedulerFactoryBean myScheduler2() throws IOException {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
// schedulerFactoryBean.setDataSource(dataSource); // 使用 application.properties 中的数据源
schedulerFactoryBean.setOverwriteExistingJobs(true);
schedulerFactoryBean.setJobFactory(jobFactory);
schedulerFactoryBean.setQuartzProperties(quartzProperties()); // 使用 quartz.properties 中的数据源
schedulerFactoryBean.setSchedulerName("myScheduler2");
schedulerFactoryBean.setStartupDelay(2);// 延迟两秒启动
schedulerFactoryBean.setAutoStartup(true);
return schedulerFactoryBean;
}
private Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
Properties properties = propertiesFactoryBean.getObject();
return properties;
}
}
5. JobController
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.codingos.springboot.model.JobInfo;
@RestController
public class JobController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private Scheduler myScheduler; // 这个注入应该和 config 类中 @Bean 的方法名相同
@Autowired
private Scheduler myScheduler2; // 这个注入应该和 config 类中 @Bean 的方法名相同
/**
* 创建Job
*/
@PostMapping("/createJob")
public void createJob(@RequestBody JobInfo jobInfo) {
Scheduler scheduler = getScheduler(jobInfo.getSchedulerName());
Class<? extends Job> jobClass = null;
try {
jobClass = (Class<? extends Job>) Class.forName(jobInfo.getJobClassName());
} catch (ClassNotFoundException e) {
logger.error("create Job " + jobInfo.getJobName() + " error: " + e.getMessage(), e);
}
JobKey jobKey = new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobKey).storeDurably().build();
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobInfo.getCron());
TriggerKey triggerKey = new TriggerKey(jobInfo.getTriggerName(), jobInfo.getTriggerGroup());
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).forJob(jobDetail).withSchedule(scheduleBuilder).build();
try {
scheduler.scheduleJob(jobDetail, cronTrigger);
scheduler.pauseJob(jobKey); // 如果此处不暂停, 就会直接运行job
} catch (SchedulerException e) {
logger.error("create Job " + jobInfo.getJobName() + " error: " + e.getMessage(), e);
}
}
@PostMapping("/jobStrat")
public void jobStrat(@RequestBody JobInfo jobInfo) {
Scheduler scheduler = getScheduler(jobInfo.getSchedulerName());
JobKey jobKey = new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
try {
scheduler.resumeJob(jobKey); // 恢复执行job
} catch (SchedulerException e) {
logger.error("Job " + jobInfo.getJobName() + " start error: " + e.getMessage(), e);
}
}
@PostMapping("/jobStop")
public void jobStop(@RequestBody JobInfo jobInfo) {
Scheduler scheduler = getScheduler(jobInfo.getSchedulerName());
JobKey jobKey = new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
try {
scheduler.pauseJob(jobKey); // 暂停运行job
} catch (SchedulerException e) {
logger.error("Job " + jobInfo.getJobName() + " stop error: " + e.getMessage(), e);
}
}
@PostMapping("/jobEdit")
public void jobEdit(@RequestBody JobInfo jobInfo) {
Scheduler scheduler = getScheduler(jobInfo.getSchedulerName());
JobKey jobKey = new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
try {
TriggerKey triggerKey = new TriggerKey(jobInfo.getTriggerName(), jobInfo.getTriggerGroup());
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobInfo.getCron());
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).forJob(jobKey).withSchedule(scheduleBuilder).build();
scheduler.rescheduleJob(triggerKey, cronTrigger); // 更新对应的 trigger
} catch (SchedulerException e) {
logger.error("Job " + jobInfo.getJobName() + " edit error: " + e.getMessage(), e);
}
}
@PostMapping("/jobDelete")
public void jobDelete(@RequestBody JobInfo jobInfo) {
Scheduler scheduler = getScheduler(jobInfo.getSchedulerName());
JobKey jobKey = new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
try {
scheduler.deleteJob(jobKey); // 删除job和对应的trigger
} catch (SchedulerException e) {
logger.error("Job " + jobInfo.getJobName() + " stop error: " + e.getMessage(), e);
}
}
private Scheduler getScheduler(String schedulerName) {
Scheduler scheduler = null;
switch (schedulerName) {
case "myScheduler":
scheduler = myScheduler;
break;
case "myScheduler2":
scheduler = myScheduler2;
break;
default:
break;
}
return scheduler;
}
}
6. Job 类
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import com.codingos.springboot.service.Job1Service;
public class Job1 extends QuartzJobBean {
@Autowired
private Job1Service job1Service;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
job1Service.service1();
}
}
7. JobInfo 类
public class JobInfo {
private String jobName;
private String jobGroup;
private String jobClassName;
private String triggerName;
private String triggerGroup;
private String schedulerName;
private String prevExecuteTime;
private String nextExecuteTime;
private String cron;
private String triggerState;
public JobInfo() {
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public String getTriggerState() {
return triggerState;
}
public void setTriggerState(String triggerState) {
this.triggerState = triggerState;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
public String getTriggerName() {
return triggerName;
}
public void setTriggerName(String triggerName) {
this.triggerName = triggerName;
}
public String getTriggerGroup() {
return triggerGroup;
}
public void setTriggerGroup(String triggerGroup) {
this.triggerGroup = triggerGroup;
}
public String getPrevExecuteTime() {
return prevExecuteTime;
}
public void setPrevExecuteTime(String prevExecuteTime) {
this.prevExecuteTime = prevExecuteTime;
}
public String getNextExecuteTime() {
return nextExecuteTime;
}
public void setNextExecuteTime(String nextExecuteTime) {
this.nextExecuteTime = nextExecuteTime;
}
public String getJobClassName() {
return jobClassName;
}
public void setJobClassName(String jobClassName) {
this.jobClassName = jobClassName;
}
public String getSchedulerName() {
return schedulerName;
}
public void setSchedulerName(String schedulerName) {
this.schedulerName = schedulerName;
}
}
最后, 说一下, 如果是 SpringBoot 2.x 集成 Quartz 框架, 添加依赖就非常方便了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
来源:湖北网站优化
SpringBoot 1.5.x 集成 Quartz 任务调度框架的更多相关文章
- maven项目集成Quartz定时任务框架,实现批处理功能
一.Quartz简介 主要做定时任务,即:在指定时间点或时间段,执行某项任务,可设置执行次数.时间间隔等. 二.Springcloud简介 对比传统的.庞大的.复杂的.以ssm或ssh为框架的web项 ...
- quartz任务调度框架与spring整合
Quartz是什么? Quartz 是一种功能丰富的,开放源码的作业调度库,可以在几乎任何Java应用程序集成 - 从最小的独立的应用程序到规模最大电子商务系统.Quartz可以用来创建简单或复杂的日 ...
- (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系统 ...
- Quartz 任务调度框架之Hello World
0x01 什么是Quartz? Quartz是一个完全由java编写的开源作业调度框架. 0x02 实战Quartz Hello World 创建Maven项目,POM 文件配置如下: <pro ...
- Quartz —— 任务调度框架
一.Quartz Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现.该项目于 2009 年被 Terracotta 收购,目前是 Terrac ...
- Spring_Spring集成Quartz定时任务框架介绍和Cron表达式详解
在JavaEE系统中,我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等.我们可以使用java.util.Timer结合java.util.TimerTask来完成这项工作,但 ...
- Spring集成Quartz定时任务框架介绍
在JavaEE系统中,我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等.我们可以使用java.util.Timer结合java.util.TimerTask来完成这项工作,但 ...
- (转)Java任务调度框架Quartz入门教程指南(四)Quartz任务调度框架之触发器精讲SimpleTrigger和CronTrigger、最详细的Cron表达式范例
http://blog.csdn.net/zixiao217/article/details/53075009 Quartz的主要接口类是Schedule.Job.Trigger,而触发器Trigge ...
随机推荐
- js interval ,timeout
var inter; intervatest("2019-08-22 09:12:00"); function intervatest(str) { ShowCountDown(s ...
- ABP框架没有httpPost,httpget,httpput特性
需要引用一下组件, Microsoft.AspNetCore.Mvc
- JAVAEE 和项目开发(第四课:HTTP的响应格式和响应状态码)
HTTP 协议之响应 响应格式的结构: 响应行(状态行):HTTP 版本.状态码.状态消息 响应头:消息报头,客户端使用的附加信息 空行:响应头和响应实体之间的,必须的. 响应实体:正文,服务器返回给 ...
- HZNU-ACM寒假集训Day1小结 STL 并查集
常用STL 1.优先队列 priority_queue 内部是用堆(heap)实现的 priority_queue<int> pq; 默认为一个“越小的整数优先级越低的优先队列” 对于一些 ...
- Windows10 与 WSL(Ubuntu)的文件互访
从WSL访问win10的文件 > cd /mnt 从win10访问WSL的文件 打开Ubuntu > explorer.exe . (后面的点不要漏掉)
- [XNUCA2019Qualifier]EasyPHP
0x00 知识点 预期解中知识点: htaccess生效 如果尝试上传htaccess文件会发现出现响应500的问题,因为文件尾有Just one chance 这里采用# \的方式将换行符转义成普通 ...
- JZOJ-2019-11-5 B组
T1 给出一二维01矩阵\(f_{i,j}\), 定义点\((x_a, y_a), (x_b, y_b)\)的「距离」为\(max\{|x_a-x_b|, |y_a-y_b|\}\) 求出一矩阵\(w ...
- 关于mysql/apache/nginx的配置文件配置
2015.5.12 mysql中可以通过函数查看用户列表/查看当前用户以及删除用户,方法百度之,忘了 /etc/php5/fpm/php.ini memory_limit修改之前为128M apach ...
- 面试题:你使用过concurrent包下的那些类?
1.executor接口,使用executor接口的子接口ExecutorService用来创建线程池2.Lock接口下的ReentrantLock类,实现同步,比如三个线程循环打印ABCABCABC ...
- SDWebImage清理缓存
[[SDImageCache sharedImageCache] getSize]//计算缓存的大小,单位B float tmpSize = [[SDImageCache sharedImageCac ...