Quartz-Spring定时任务器持久化,通过Service动态添加,删除,启动暂停任务
原文地址:https://blog.csdn.net/ljqwstc/article/details/78257091
首先添加maven的依赖:
<!--quartz定时任务-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
spring配置文件中添加如下bean
<!--
自动装配类
@Autowired
private Scheduler scheduler;
-->
<!-- quartz持久化存储 -->
<!--实现动态配置只需定义一下schedulerbean就可以了-->
<bean name="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="true">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<!-- 线程池配置 -->
<prop key="org.quartz.threadPool.class">${org.quartz.threadPool.class}</prop>
<prop key="org.quartz.threadPool.threadCount">${org.quartz.threadPool.threadCount}</prop>
<prop key="org.quartz.threadPool.threadPriority">${org.quartz.threadPool.threadPriority}</prop>
<prop key="org.quartz.jobStore.misfireThreshold">${org.quartz.jobStore.misfireThreshold}</prop>
<!-- JobStore 配置 -->
<prop key="org.quartz.jobStore.class">${org.quartz.jobStore.class}</prop>
<!-- 集群配置 -->
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">15000</prop>
<prop key="org.quartz.jobStore.maxMisfiresToHandleAtATime">1</prop>
<!-- 数据表设置 -->
<prop key="org.quartz.jobStore.tablePrefix">${org.quartz.jobStore.tablePrefix}</prop>
<prop key="org.quartz.jobStore.dataSource">${org.quartz.jobStore.dataSource}</prop>
</props>
</property>
</bean>
1.一般公司项目中都已经定义好了dataSource,比如我们公司是用DruidDataSource,所以直接拿来用就可以了。如果没有的话,需要配置一个dataSource,这里就不阐述了。
3.Scheduler简单说相当于一个容器一样,里面放着jobDetail和Trriger
4.其他的一些配置可以根据自己的业务需求,到quartz的官网查看配置文档进行添加。
这个是quartz.properties文件
#============================================================================
# Configure Datasources
#============================================================================
#JDBC驱动
#org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
#org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/quartz?characterEncoding=utf-8
#org.quartz.dataSource.myDS.user = root
#org.quartz.dataSource.myDS.password = root
#org.quartz.dataSource.myDS.maxConnections =5
#集群配置
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true org.quartz.jobStore.misfireThreshold: 60000 #============================================================================
# Configure JobStore
#============================================================================ #默认配置,数据保存到内存
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#持久化配置
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.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:myDS
这个是quartz官方的表,运行就可以了,就建表成功了。
#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS; CREATE TABLE QRTZ_JOB_DETAILS
(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_SIMPLE_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_CRON_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(200) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_BLOB_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_CALENDARS
(
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_FIRED_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_SCHEDULER_STATE
(
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_LOCKS
(
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; commit;
ok,到这里,我们需要的配置基本完成,接下来,就是怎么样去创建任务,实现任务的动态添加,修改。
下面详细解释下实现方法:
public class ScheduleJob implements Serializable { private static final long serialVersionUID = -5115028108119830917L;
/**
* 任务名称
*/
private String jobName;
/**
* 任务分组
*/
private String jobGroup;
/**
* 触发器名称(默认和任务名称相同)
*/
private String triggerName;
/**
* 触发器分组(默认和任务分组相同)
*/
private String triggerGroup;
/**
* 任务需要调用的是哪个类的类名
*/
private String className;
/**
* 任务需要调用的是哪个类的方法名
*/
private String methodName;
/**
* 方法所需参数数组
*/
private ArrayList paramArray;
/**
* 任务运行时间表达式
*/
private String cron;
/**
* 任务运行时间(特指只运行一次的任务)
*/
private String runDate;
/**
* 任务描述
*/
private String desc;
getter and setter.....
}
@PersistJobDataAfterExecution
public class QuartzJobFactory implements Job { /**
* The constant logger.
*/
private static final Logger logger = LoggerFactory.getLogger(Constants.LOG_SYSTEM_RUN); public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
//获取service层接口名和接口方法名
String springBeanName = scheduleJob.getClassName();
String methodName = scheduleJob.getMethodName();
//获取参数数组和参数类型数组
ArrayList paramArray = scheduleJob.getParamArray();
Class[] paramType = new Class[paramArray.size()];
for (int i = 0; i < paramArray.size(); i++) {
paramType[i] = paramArray.get(i).getClass();
}
/**
* 反射运行service层的方法
*/
Object bean = SpringContextsUtil.getBean(springBeanName);
Method method = ReflectionUtils.findMethod(bean.getClass(), methodName, paramType);
ReflectionUtils.invokeMethod(method, bean, paramArray.toArray()); logger.info("任务名称 = [" + scheduleJob.getJobName() + "]," +
"任务调用的类=[" + scheduleJob.getClassName() + "]," +
"任务调用的方法=[" + scheduleJob.getMethodName() + "]---->>成功启动运行");
}
}
@PersistJobDataAfterExecution
如果不支持并发
@disallowconcurrentexecution
@Component
public class SpringContextsUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; public static Object getBean(String beanName) throws BeansException {
return applicationContext.getBean(beanName);
} public static <T> T getBean(String beanName, Class<T> clazs) {
return applicationContext.getBean(beanName, clazs);
} @Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextsUtil.applicationContext = applicationContext;
}
}
public interface QuartzProducer { /**
* 添加简单任务,只运行一次的任务
*
* @param jobName
* @param jobGroup
* @param className
* @param methodName
* @param paramArray
* @param runDateTime 格式:yyyyMMddHHmmss
* @throws SchedulerException
* @throws ParseException
*/
public void addSimpleJob(String jobName, String jobGroup, String className, String methodName, ArrayList paramArray, String runDateTime) throws SchedulerException, ParseException; /**
* 添加循环任务,特定时间循环运行,例如每个星期3,12点运行等
*
* @param jobName
* @param jobGroup
* @param className
* @param methodName
* @param paramArray
* @param cron
* @throws SchedulerException
*/
public void addCronJob(String jobName, String jobGroup, String className, String methodName, ArrayList paramArray, String cron) throws SchedulerException; /**
* 修改简单任务,一般指修改运行时间
*
* @param jobName
* @param jobGroup
* @param runDateTime 格式:yyyyMMddHHmmss
*/
public void updateSimpleJob(String jobName, String jobGroup, String runDateTime) throws SchedulerException, ParseException; /**
* 修改cron任务,一般指修改循环运行时间
*
* @param jobName
* @param jobGroup
* @param cron
*/
public void updateCronJob(String jobName, String jobGroup, String cron) throws SchedulerException; /**
* 移除任务
*
* @param jobName
* @param jobGroup
*/
public void deleteJob(String jobName, String jobGroup) throws SchedulerException; /**
* 移除所有任务
*/
public void deleteAll() throws SchedulerException; /**
* 暂停任务
*
* @param jobName
* @param jobGroup
*/
public void pauseJob(String jobName, String jobGroup) throws SchedulerException; /**
* 暂停所有任务
*/
public void pauseAll() throws SchedulerException; /**
* 恢复某个任务
*
* @param jobName
* @param jobGroup
*/
public void resumeJob(String jobName, String jobGroup) throws SchedulerException; /**
* 恢复所有
*/
public void resumeAll() throws SchedulerException; /**
* 关闭任务调度器
*/
public void shutDown() throws SchedulerException; /**
* 开启任务调度器
*/
public void startScheduler() throws SchedulerException;
}
实现类:
//定义该bean的name为"quartzProducer"
@Service("quartzProducer")
public class QuartzProducerImpl implements QuartzProducer { //虽然在Spring配置中配置的是SchedulerFactoryBean这个类,但是我们自动转配就写这样,一样是可以使用的
@Autowired
private Scheduler scheduler; @Override
public void addSimpleJob(String jobName, String jobGroup, String className, String methodName, ArrayList paramArray, String runDateTime) throws SchedulerException, ParseException {
//判断是否已存在相同jobName,jobGroup,若存在则删除
if (scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroup)) != null) {
deleteJob(jobName, jobGroup);
}
JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(jobName, jobGroup).build();
//任务具体执行的内容封装,返回给job统一入口
ScheduleJob job = new ScheduleJob(jobName, jobGroup, jobName, jobGroup, className, methodName, paramArray, null, runDateTime, null);
//将我自定义的POJO类存放到DataMap中
jobDetail.getJobDataMap().put("scheduleJob", job);
//创建SimpleTrigger,在特定时间仅运行一次
Date runDate = DateUtils.parseDate(runDateTime, DateStyle.YYYYMMDDHHMMSS.getValue());
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup).
startAt(runDate).build();
scheduler.scheduleJob(jobDetail, trigger);
} }
Quartz-Spring定时任务器持久化,通过Service动态添加,删除,启动暂停任务的更多相关文章
- jquery动态添加删除div--事件绑定,对象克隆
我想做一个可以动态添加删除div的功能.中间遇到一个问题,最后在manong123.com开发文摘 版主的热心帮助下解答了(答案在最后) 使用到的jquery方法和思想就是:事件的绑定和销毁(unbi ...
- 编辑 Ext 表格(一)——— 动态添加删除行列
一.动态增删行 在 ext 表格中,动态添加行主要和表格绑定的 store 有关, 通过对 store 数据集进行添加或删除,就能实现表格行的动态添加删除. (1) 动态添加表格的行 gridS ...
- 用Javascript动态添加删除HTML元素实例 (转载)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- js实现网页收藏功能,动态添加删除网址
<html> <head> <title> 动态添加删除网址 </title> <meta charset="utf-8"&g ...
- jQuery动态添加删除CSS样式
jQuery框架提供了两个CSS样式操作方法,一个是追加样式addClass,一个是移除样式removeClass,下面通过一个小例子讲解用法. jQuery动态追加移除CSS样式 <!DOCT ...
- JS动态添加删除html
本功能要求是页面传一个List 集合给后台而且页面可以动态添加删除html代码需求如下: 下面是jsp页面代码 <%@ page language="java" pageEn ...
- C#控制IIS动态添加删除网站
我的目的是在Winform程序里面,可以直接启动一个HTTP服务端,给下游客户连接使用. 查找相关技术,有两种方法: 1.使用C#动态添加网站应用到IIS中,借用IIS的管理能力来提供HTTP接口.本 ...
- Angular-表单动态添加删除
angular本身不允许去操作DOM,在angular的角度来说,所有操作都以数据为核心,剩下的事情由angular来完成.所以说,想清楚问题的根源,解决起来也不是那么困难. 前提 那么,要做的这个添 ...
- jQuery动态添加删除select项
// 添加 function col_add() { var selObj = $("#mySelect"); var value="value"; var t ...
随机推荐
- 【MM系列】SAP库龄报表逻辑理解
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP库龄报表逻辑理解 第一篇 ...
- 老K漫谈区块链的共识(3)——分布式系统和区块链共识
1. 啥是分布式系统 当我们评价一个新的事物或者介绍一个新的技术的时候,我们不能架空历史和环境,新的事物不可能脱离历史和环境凭空诞生.任何新的事物和新的技术总是或多或少的,与旧的事件以及过去的技术有所 ...
- CISCO ACL配置
ACL:access(访问)control(控制)list(列表),用来实现防火墙规则. 访问控制列表的原理对路由器接口来说有两个方向出:已经经路由器的处理,正离开路由器接口的数据包入:已经到达路由器 ...
- 18年10月份最新免费申请微软OneDrive5TB云盘超详细教程!(已亲测!)
本人已于今天10月23日亲测,成功获取微软OneDrive5T云盘! 第一步:.打开申请链接学生版:https://signup.microsoft.com/signup?sku=student教师版 ...
- 使用selenium时,使用从系统启动浏览器与通过自动化驱动方式启动浏览器控件ID不一样解决方法
最近遇到一个怪事,通过正常打开浏览器,按照正常的web登录然后点击进入系统流程,将各控件的ID识别成功,然后使用 python3+selenium写好脚本,高高兴兴的用脚本跑时老是提示找不到控件,然后 ...
- Announcing the Updated NGINX and NGINX Plus Plug‑In for New Relic (Version 2)
In March, 2013 we released the first version of the “nginx web server” plug‑in for New Relic monitor ...
- InfluxDB基本概念和操作
InfluxDB基本概念 1.数据格式 在 InfluxDB 中,我们可以粗略的将要存入的一条数据看作一个虚拟的 key 和其对应的 value(field value).格式如下: 1 cpu_us ...
- JS DOM 实现删除和添加的功能
<!DOCTYPE html> <html> <head> <title>发表评论</title> <link rel="s ...
- cf 20190307 Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round)
B. Mike and Children time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- 【Java8】@FunctionalInterface
阅读目录 什么是函数式接口(Functional Interface) 函数式接口用途 关于@FunctionalInterface注解 函数式接口里允许定义默认方法 函数式接口里允许定义静态方法 函 ...