《 Quartz-2.2.1 任务调度框架在Java项目中的使用实例 》
本实例是基于Quartz 2.2.1 版本为中心,也是目前最新的Quartz任务调度框架。
目前在 J2EE 项目开发的过程中用的最多的任务调度框架为 Quartz,项目完成后,总结一下,主要为一些核心 API 和接口的概念比较重要。
一、Quartz-2.2.1使用实例
下面是一个通用的项目实例,高度抽象的实例,创建一个任务调度,三个任务。
Common
package com.etc.clear.img.common;
import com.etc.clear.img.job.ClearImgJob;
import com.etc.clear.img.job.SendImgJob;
import com.etc.clear.img.job.UnzipImgJob;
import com.etc.clear.img.utils.ImgQuartzUtils;
/**
* 初始化图片清理任务
* <p>
*
* @ClassName : ClsImgUtils
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @ContactInformation : 1461522031@qq.com/huazai6789@aliyun.com
* </p>
* <p>
* @Date : 2017年12月20日 下午4:38:52
* </p>
*
* <p>
* @Version : V1.0.0
* </p>
*
*/
public class InitImgQuartzCommon {
/**
* 初始化图片清除任务
* <p>
*
* @Title : initClearImg
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @Date : 2018年1月2日 下午2:28:08
* </p>
*/
public void startClearImg() {
try {
// 使用 SimpleTrigger 进行图片处理
// QuartzUtils.addJobBySimple("job01", "trigger01",
// UnzipImgJob.class, 3);
// QuartzUtils.addJobBySimple("job02", "trigger02",
// SendImgJob.class, 4);
// QuartzUtils.addJobBySimple("job03", "trigger03",
// ClearImgJob.class, 5);
// 使用 CronTrigger 进行图片处理
// 压缩文件
ImgQuartzUtils.addJobByCron("job01", "trigger01", UnzipImgJob.class, "*/5 * * * * ?");
// 发送文件
ImgQuartzUtils.addJobByCron("job02", "trigger02", SendImgJob.class, "*/5 * * * * ?");
// 删除文件
ImgQuartzUtils.addJobByCron("job03", "trigger03", ClearImgJob.class, "*/5 * * * * ?");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.toString());
}
}
}
Job
package com.etc.clear.img.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* 定义清除服务器图片的任务
* <p>
*
* @ClassName : ClearImgJob
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @ContactInformation : 1461522031@qq.com/huazai6789@aliyun.com
* </p>
*
* @Date : 2018年1月3日 下午1:19:11
*
* @Version : V1.0.0
*
*/
public class ClearImgJob implements Job {
/**
* 清除图片任务
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("================ 进入图片《删除》阶段 ....");
}
}
package com.etc.clear.img.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* 发送服务器图片任务
* <p>
*
* @ClassName : SendImgJob
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @ContactInformation : 1461522031@qq.com/huazai6789@aliyun.com
* </p>
*
* @Date : 2018年1月3日 下午1:19:39
*
* @Version : V1.0.0
*
*/
public class SendImgJob implements Job {
/**
* 发送压缩包任务
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("================ 进入图片《发送》阶段 ....");
}
}
package com.etc.clear.img.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* 压缩服务器图片任务
* <p>
*
* @ClassName : UnzipImgJob
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @ContactInformation : 1461522031@qq.com/huazai6789@aliyun.com
* </p>
*
* @Date : 2018年1月3日 下午1:16:30
*
* @Version : V1.0.0
*
*/
public class UnzipImgJob implements Job {
/**
* 压缩图片任务
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("================ 进入图片《压缩》阶段 ....");
}
}
package com.etc.clear.img.utils;
import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 任务调度工具类
* <p>
*
* @ClassName : QuartzUtils
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @ContactInformation : 1461522031@qq.com/huazai6789@aliyun.com
* </p>
*
* @Date : 2018年1月3日 下午1:21:13
*
* @Version : V1.0.0
*
*/
public class ImgQuartzUtils {
private final static String JOB_GROUP_NAME = "QUARTZ_JOBGROUP_NAME"; // 任务组
private final static String TRIGGER_GROUP_NAME = "QUARTZ_TRIGGERGROUP_NAME"; // 触发器组
private static Logger log = LoggerFactory.getLogger(ImgQuartzUtils.class);// 日志打印
/**
* 创建 SimpleTrigger
* <p>
*
* @Title : addJob
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @Date : 2017年12月29日 下午4:49:52
* </p>
*
* @throws Exception
*/
public static void addJobBySimple(String jobName, String triggerName, Class<? extends Job> jobClass, int seconds)
throws Exception {
log.info("================== 初始化 =================");
// 创建一个SchedulerFactory工厂实例
SchedulerFactory factory = new StdSchedulerFactory();
// 通过SchedulerFactory工厂构建Scheduler容器对象
Scheduler scheduler = factory.getScheduler();
log.info("=================== 初始化完成 ===================");
log.info("============== 将作业添加到任务作业调度中 ==================");
// 构建一个jobDetail 作业实例
JobDetail detail = JobBuilder.newJob(jobClass) // 构建一个新任务
.withIdentity(jobName, JOB_GROUP_NAME) // 给新任务起名和分组
.build(); // 绑定作业
// 构建一个SimpleTrigger的触发器
Trigger trigger = TriggerBuilder.newTrigger()// 创建一个新的TriggerBuilder
.withIdentity(triggerName, TRIGGER_GROUP_NAME)// 给触发器起名和分组
.startNow()// 立即执行
.withSchedule(
// 定义触发规则
SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(seconds) // 时间间隔
.repeatForever() // 一直执行
).build();// 绑定出发规则
// 将job任务和trigger触发器添加到Scheduler容器中
scheduler.scheduleJob(detail, trigger);
// 启动Quartz任务调度
scheduler.start();
}
/**
* 创建 CronTrigger
* <p>
*
* @Title : addJob
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @Date : 2017年12月29日 下午4:49:52
* </p>
*
* @throws Exception
*/
public static void addJobByCron(String jobName, String triggerName, Class<? extends Job> jobClass, String cron)
throws Exception {
log.info("================== 初始化 =================");
// 创建一个SchedulerFactory工厂实例
SchedulerFactory factory = new StdSchedulerFactory();
// 通过SchedulerFactory工厂构建Scheduler容器对象
Scheduler scheduler = factory.getScheduler();
log.info("=================== 初始化完成 ===================");
log.info("============== 将作业添加到任务作业调度中 ==================");
// 构建一个jobDetail 作业实例
JobDetail detail = JobBuilder.newJob(jobClass) // 构建一个新任务
.withIdentity(jobName, JOB_GROUP_NAME) // 给新任务起名和分组
.build(); // 绑定作业
// 构建一个 CronSchedule 的触发器
Trigger trigger = TriggerBuilder.newTrigger()// 创建一个新的TriggerBuilder
.withIdentity(triggerName, TRIGGER_GROUP_NAME)// 给触发器起名和分组
.startNow()// 立即执行
.withSchedule(
// 定义触发规则
CronScheduleBuilder.cronSchedule(cron))
.build();// 绑定出发规则
// 将job任务和trigger触发器添加到Scheduler容器中
scheduler.scheduleJob(detail, trigger);
// 启动Quartz任务调度
scheduler.start();
}
}
Main
package com.etc.clear;
import com.etc.clear.img.common.InitImgQuartzCommon;
/**
* 程序启动入口/调用任务的类
* <p>
*
* @ClassName : ClsMain
* </p>
* <p>
* @Description : TODO
* </p>
* <p>
* @Author : HuaZai
* </p>
* <p>
* @ContactInformation : 1461522031@qq.com/huazai6789@aliyun.com
* </p>
*
* @Date : 2018年1月3日 下午1:21:56
*
* @Version : V1.0.0
*
*/
public class ApplicationMain {
public static void main(String[] args) {
// 初始化清理图片任务
InitImgQuartzCommon imgQuartzCommon = new InitImgQuartzCommon();
// 启动图片清理任务
imgQuartzCommon.startClearImg();
}
}
关于这个实例使用到的Jar包:http://download.csdn.net/download/hello_world_qwp/10178554
Quartz-2.2.1 任务调度框架在Java项目中的使用实例 Demo下载地址:http://download.csdn.net/download/hello_world_qwp/10198020
二、相关简介
1、Quartz是什么?
Quartz是一个完全由java编写的开源作业调度框架。
Quartz框架的核心是调度器。调度器负责管理Quartz应用运行时环境。调度器不是靠自己做所有的工作,而是依赖框架内一些非常重要的部件。Quartz不仅仅是线程和线程管理。为确保可伸缩性,Quartz采用了基于多线程的架构。启动时,框架初始化一套worker线程,这套线程被调度器用来执行预定的作业。这就是Quartz怎样能并发运行多个作业的原理。Quartz依赖一套松耦合的线程池管理部件来管理线程环境。
2、Quartz的应用场景?
场景一:更新静态数据
场景二:提醒和报警
场景三:监听事务
场景四:定时作业
3、关于Quartz框架的部分核心 API
Scheduler:
作用:Scheduler接口是Quartz最核心的接口。Scheduler维护着JobDetail和Trigger的注册信息。一旦注册成功,Scheduler负责执行和Job关联的触发器。
一个Scheduler实例可以视为一个调度作业容器。可以通过start和shutdown方法来控制它的生命周期。
Job:
作用:开发者实现该接口定义需要执行的作业。JobExecutionContext类提供调度上下文的各种信息。
JobDetail:
作用:用于定义Job实例。
JobDetail接口有两个boolean属性:
isDurable:如果设为false,则对应的Job一旦没有关联的触发器,就会被Scheduler自动删除。
requestsRecovery:如果设为true,当Job执行中遇到硬中断(例如运行崩溃、机器断电等),Scheduler会重新执行。这种情况下,JobExecutionContext.isRecovering()会返回ture。
Trigger:
作用:定义Job执行的触发规则。
Quartz中有多种触发器,最常用的是SimpleTrigger 和 CronTrigger。
SimpleTrigger:
一般用于只执行一次或在指定时间执行的作业;
CronTrigger:一般用于周期性执行(例如,每日执行、每周执行)的作业,需要按照指定的时间表达式规则设置调度时间。
Priority:这个属性表示Trigger的权重。当两个Trigger触发时间相同时,权重大的那个先执行。Quartz默认的权重值为5。
Misfire Instruction:在Trigger接口中可以设置错过触发处理机制。就是说在指定触发的时间点由于某种原因错过执行的时机了,这时如何去处理。
Job和Trigger的关系:
多个Job可以依赖于一个Trigger;多个Trigger也可以关联一个Job。
但是,从最佳实践来看,最好让Job和Trigger保持一对多的关系,这样更便于管理。
JobBuilder:
作用:用来定义、构建Jobdetail实例。
TriggerBuilder:
作用:用来定义、构建Trigger实例。
JobDataMap:
JobDetail接口中持有JobDataMap类。开发者可以将作业执行时需要的参数或对象填入这个类中。
填入数据和获取数据的方式很类似Json。
JobKey 和 TriggerKey:
在Quartz中,可以分别通过JobKey和TriggerKey来唯一地识别一个Job或一个Trigger。
这两个Key都有两个关键属性:name和group。