Quartz的三个核心概念:调度器、任务、触发器,三者之间的关系是:
一个作业,比较重要的三个要素就是Schduler,jobDetail,Trigger;而Trigger 对于job而言就好比一个驱动器;没有触发器来定时驱动作业,作业就无法运行;对于Job而言, 一个job可以对应多个Trigger,但对于Trigger而言,一个Trigger只能对应一个job;所以一 个Trigger 只能被指派给一个 Job;如果你需要一个更复杂的触发计划,你可以创建多个 Trigger并指派它们给同一个 Job。
Scheduler的创建方式:
(1)StdSchedulerFactory:
Quartz默认的SchedulerFactory
- 使用一组参数(java.util.Properties)来创建和初始化Quartz调度器
- 配置参数一般存储在quartz.properties文件中
- 调用getScheduler方法就能创建和初始化调度器对象
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
用法一:输出调度器开始的时间(重要:使得任务和触发器进行关联):
Date scheduleJob(JobDetail jobDetail, Trigger trigger)
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("调度器开始的时间是:"+dateFormat.format(scheduler.scheduleJob(job, trigger)));
用法二:启动任务调度:
void start();
scheduler.start();
用法三:任务调度挂起,即暂停操作
void standby()
// Scheduler执行2秒后自动挂起
Thread.sleep(2000L);
scheduler.standby();
// Scheduler执行5秒后自动开启
Thread.sleep(5000L);
scheduler.start();
用法四:关闭任务调度
void shutdown()
shutdown(true):表示等待所有正在执行的job执行完毕之后,再关闭Scheduler; shutdown(false):表示直接关闭Scheduler
入门案例:
项目结构:
pom.xml
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version> <!--5.1.6-->
<scope>runtime</scope>
</dependency>
QuartzJob类(任务类)
package test.quartz;
import lombok.Data;
import org.quartz.Job;
import java.io.Serializable;
@Data
public class QuartzJob implements Serializable {
//任务名
private String taskName;
//组名
private String groupName;
//corn表达式
private String cornExpr;
//具体任务实现类
private Class<? extends Job> clazz;
//配置类
private Object obj;
}
QuartzJobImpl类(任务实现类)
package test.quartz;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 任务实现类
*/
public class QuartzJobImpl implements InterruptableJob {
private JobKey jobKey;
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// 定义时间
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
System.out.println("进入任务实现类,处理业务逻辑 ->"+dateString);
jobKey = jobExecutionContext.getJobDetail().getKey();
//获取任务类
Object obj = jobExecutionContext.getJobDetail().getJobDataMap().get("obj");
runTask(obj);
}
public void runTask(Object object) {
//配置类名
String className = object.getClass().getSimpleName();
System.out.println("className=" + className);
//根据配置类名做相应处理
if ("DemoConfig".equals(className)) {
System.out.println("good good study");
} else {
System.out.println("day day sleep");
}
}
public void interrupt() throws UnableToInterruptJobException {
}
}
QuarztJobConfig 类(任务配置类):主要用于配置任务,是否启动任务等
package test.quartz;
import lombok.Data;
import java.io.Serializable;
/**
* 任务配置类
*/
@Data
public class QuarztJobConfig implements Serializable {
private String name;
private Integer state;
}
QuartzManager类:任务调度管理
package test.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
/**
* 任务调度管理器
*/
public class QuartzManager {
private Scheduler scheduler;
public void addJob(QuartzJob job){
System.out.println("enter addJob");
// 任务名 组名
JobKey jobKey = new JobKey(job.getTaskName(), job.getGroupName());
// 任务执行类
JobDetail jobDetail = JobBuilder.newJob(job.getClazz()).withIdentity(jobKey).build();
//把配置信息 放入jobdatamap中
jobDetail.getJobDataMap().put("obj",job.getObj());
//触发器
TriggerKey triggerKey = new TriggerKey(job.getTaskName(), job.getGroupName());
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCornExpr())
.withMisfireHandlingInstructionDoNothing())
.build();
/* Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
// 2秒执行一次
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(2))
// 立即执行
.startNow()
.build();*/
StdSchedulerFactory factory = new StdSchedulerFactory();
try {
scheduler = factory.getScheduler();
//将任务作业 和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail,trigger);
//启动
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 修改定时任务的时间
* @param job
* @throws SchedulerException
*/
public void modify(QuartzJob job) throws SchedulerException {
TriggerKey triggerKey = new TriggerKey(job.getTaskName(), job.getGroupName());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
String oldExp = trigger.getCronExpression();
String newExp= job.getCornExpr();
if (!oldExp.equals(newExp)) {
trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(newExp))
.startNow().build();
scheduler.rescheduleJob(triggerKey,trigger);
}
}
}
QuartzTest 测试类:
package test.quartz;
import org.quartz.SchedulerException;
/**
* 测试类
*/
public class QuartzTest {
private static final String DATA_BACKUP = "data_backup";
private static final String DATA_GROUP = "data_group";
public static void main(String[] args) throws SchedulerException {
QuarztJobConfig taskConfig = new QuarztJobConfig();
taskConfig.setName("任务配置信息");
taskConfig.setState(1); //任务配置状态
QuartzJob taskJob = new QuartzJob();
taskJob.setTaskName(DATA_BACKUP);
taskJob.setGroupName(DATA_GROUP);
taskJob.setCornExpr("0 0/1 11 * * ?");
//具体任务实现类
taskJob.setClazz(QuartzJobImpl.class);
taskJob.setObj(taskConfig);
//创建任务执行
QuartzManager manager = new QuartzManager();
manager.addJob(taskJob);
//修改定时任务时间
taskJob.setCornExpr("0 0/1 15 * * ?");
manager.modify(taskJob);
}
}
Quartz建表语句(持久化到数据库)
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)
);
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)
);
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)
);
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)
);
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)
);
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)
);
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)
);
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
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)
);
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)
);
CREATE TABLE QRTZ_LOCKS
(
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);
Quartz的配置属性:quartz.properties
org.quartz.scheduler.instanceName = TestScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/hnh?characterEncoding=utf-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = xxxx
org.quartz.dataSource.myDS.maxConnections = 5
#连接数据库检测语句
org.quartz.dataSource.myDS.validationQuery = select 1 from dual
测试结果: