上一篇中,拥有一个简单使用Quartz的例子;
这一篇,将包括对Quartz的一些详细使用。
文章目录
JobDetail 类
JobDetail为Job实例提供了许多设置属性,
JobDetail重要属性:
设定任务类、Job名称、组名称 和JobDataMap:JobBulider.newJob(MyJob.class).withIdentity("job1","group1").usingJobData("message","信息值").build();
获取名称: JobDetail.getKey().getName() // job1
获取组的名称:JobDetail.getKey().getGroup() // group1 , 默认DEFAULT
获取任务类: JobDetail.getJobClass().getName() // com.example.MyJob
获取JobDataMap:JobDetail.getJobDataMap()
JobDataMap类
- 在任务调度时,JobDataMap存储在JobExecutionContext中,可以获取。
- JobDataMap可以装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它。
- JobDataMap实现了JDK的Map接口,并添加了方便的方法来获取基本数据类型。
.usingJobData("message","信息值")
JobExecutionContext类
当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法;Job通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。
context.getJobDetail().getKey().getName() // 获取Job名称
context.getJobDetail().getKey().getGroup() // 获取Job组的名称
context.getJobDetail().getJobClass().getName() // 获取Job任务类
context.getJobDetail().getJobDataMap() // 获取JobDetail中的JobDataMap
context.getJobDetail().getJobDataMap().getString("message") //获取JobDetail中JobDataMap的message信息值
context.getTrigger().getKey().getName() // 获取Trigger名称
context.getTrigger().getKey().getGroup() // 获取Trigger组的名称
context.getTrigger().getJobDataMap() // 获取Trigger中的JobDataMap
context.getFireTime() // 获取当前任务执行时间
context.getNextFireTime() // 获取下一次任务执行时间
context.getTrigger().getStartTime() // 获取任务执行开始时间
context.getTrigger().getEndTime() // 获取任务执行结束时间
context.getJobDetail().getJobDataMap().getString("message");
或
在MyJob类中添加message的属性以及setter方法,即可在直接通过message属性获取相应值(如果Trigger和JobDetail都设置了message属性,则以Trigger设置值为准)
有状态Job和无状态Job
默认为无状态Job。每次调用Job时都会创建一个新的JobDataMap对象,想要修改其中的键值对是没有效果的。
对MyJob类添加注解**@persistJobDataAfterExecution**成为有状态Job,多次调用Job期间可以持有一些状态信息,可实现count的累加计算。
修改状态信息:context.getJobDetail().getJobDataMap().put(“count”,count);
Trigger类
设置任务开始时间、结束时间:
Trigger trigger =TriggerBulider.newTrigger()
.withIdentity("trigger1","group1")
.startat(new Date())
.endat(new Date())
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.repeatSecondlyForever(5)
.withRepeatCount(3))
.build();
获取任务开始时间、结束时间:
context.getTrigger().getStartTime() // 获取任务执行开始时间
context.getTrigger().getEndTime() // 获取任务执行结束时间
抽象触发器:
SimpleTrigger
CronTrigger
CalendarIntervalTrigger
DailyTimeIntervalTrigger
SimpleTrigger触发器
需在特定日期/时间启动,且以一个可能的间隔时间重复执行n次的Job设计的触发器。
可灵活设置开始时间/结束时间/重复次数/重复时间间隔。
CronTrigger触发器
需像日历那样按照日程类触发任务的触发器。
Cron表达式:cron表达式是一个由7个子表达式组成的字符串,这些子表达式用空格分隔,分别表示 秒、分钟、小时、月中天、月、周中天、年(可不填)。
SchedulerFactory类
一个Job 可以对应多个Trigger,但一个Trigger智能对应一个Job。
Scheduler的创建方式:
DirectSchedulerFactory
StdSchedulerFactory:
使用一组参数(java.util.Properties)来创建和初始化Quartz调度器;配置参数一般存储在quartz.properties文件中;调用getScheduler方法就能创建和初始化调度器对象。
得到SchedulerFactory实例:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
输出调度器开始时间,关联任务和触发器:
Date date =scheduler.scheduleJob(jobDetail,trigger);
启动任务调度:
scheduler.start();
挂起任务调度,暂停:
scheduler.standby();
重新启动任务调度:
scheduler.start();
重启后会连续执行挂起期间的调度任务。
关闭任务调度(true:等待所有正在执行的Job执行完毕后再关闭scheduler;false:直接关闭scheduler):
scheduler.stutdown(true);
quartz.properties文件
org.quartz.scheduler.instanceName = DefaultQuartzScheduler // 调度器实例名
org.quartz.scheduler.instanceId = AUTO // 调度器实例ID,必须唯一(集群时用到)
org.quartz.threadPool.threadCount = 10 // 处理Job的线程池个数
org.quartz.threadPool.threadPriority = 5 // 线程的优先级,1~10,默认5。
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool // 指定的线程池
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore // 作业存储设置
#org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin // 插件
#org.quartz.plugin.jobInitializer.overWriteExistingJobs = true
#org.quartz.plugin.jobInitializer.failOnFileNotFound = true
#org.quartz.plugin.jobInitializer.validating = false
Quartz监听器
- Quartz监听器主要有JobListener、TriggerListener、SchedulerListener三种。
- 全局监听器、非全局监听器。全局监听器能够接收到所有的Job/Trigger的事件通知。非全局监听器智能在其上注册的Job/Trigger的事件。
JobListener:
任务调度过程中,与任务Job相关的事件包括:Job开始执行的提示,Job执行完成的提示等。
1. 接口JobListener实现:
public class MyJobListener implements JobListener{
}
获取该JobListener的名称:
@override
public String getName(){
return this.getClass().getName();
}
Scheduler在JobDetail将要被执行时调用这个方法:
@override
public void jobToBeExecuted(JobExecutionContext context){
}
Scheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法:
@override
public void jobExecutionVetoed(JobExecutionContext context) {
}
Scheduler在JobDetail被执行之后调用这个方法:
@override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
}
2. 创建并注册一个JobListener
在scheduler.scheduleJob(jobDetail,trigger)后,scheduler.start()之前,
创建并注册一个全局的JobListener:
scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
或创建并注册一个局部的JobListener:
scheduler.getListenerManager().addJobListener(new MyJobListener(), KeyMatcher.keyEquals(JobKey.jobKey("job1","group1")));
TriggerListener:
任务调度过程中,与触发器Trigger相关的事件包括:触发器触发、触发器未正常触发、触发器完成等。
1. 接口TriggerListener实现:
public class MyTriggerListener implements TriggerListener{
private String name;
public MyTriggerListener(String name) {
this.name = name;
}
// 获取触发器名称
@Override
public String getName() {
return this.getClass().getName();
return name;
}
// 当与监听器相关联的Trigger被触发,Job上的execute()方法将被执行时,Scheduler就调用该方法。
@Override
public void triggerFired(Trigger trigger, JobExecutionContext context) {
String triggerName = trigger.getKey().getName();
String info = triggerName + " was fired";
}
// 在 Trigger 触发后,Job 将要被执行时由 Scheduler 调用这个方法。TriggerListener 给了一个选择去否决 Job 的执行。假如这个方法返回 true,这个 Job 将不会为此次 Trigger 触发而得到执行。
@Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
String triggerName = trigger.getKey().getName();
String info = triggerName + " was not vetoed";
return false; // true:表示不会执行Job方法
}
// Scheduler 调用这个方法是在 Trigger 错过触发时。你应该关注此方法中持续时间长的逻辑:在出现许多错过触发的 Trigger 时,长逻辑会导致骨牌效应。你应当保持这上方法尽量的小。
@Override
public void triggerMisfired(Trigger trigger) {
String triggerName = trigger.getKey().getName();
String info = triggerName + " misfired";
}
//Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个方法。
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) {
String triggerName = trigger.getKey().getName();
String info = triggerName + " is complete";
}
}
2. 创建并注册一个TriggerListener
在scheduler.scheduleJob(jobDetail,trigger)后,scheduler.start()之前,
创建并注册一个全局的TriggerListener:
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("myListenerName"), EverythingMatcher.allTriggers());
或创建并注册一个局部的TriggerListener:
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("myListenerName"), KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1","group1")));
SchedulerListener:
SchedulerListener会在Scheduler的生命周期中关键事件发生时被调用。与Scheduler有关的事件包括:增加一个job/trigger,删除一个job/trigger,scheduler发生严重错误,关闭scheduler等。
1. 接口SchedulerListener 实现:
- jobScheduled方法:用于部署JobDetail时调用
- jobUnscheduled方法:用于卸载JobDetail时调用
- triggerFinalized方法:当一个 Trigger 来到了再也不会触发的状态时调用这个方法。除非这个 Job 已设置成了持久性,否则它就会从 Scheduler 中移除。
- triggersPaused方法:Scheduler 调用这个方法是发生在一个 Trigger 或 Trigger 组被暂停时。假如是 Trigger 组的话,triggerName 参数将为 null。
- triggersResumed方法:Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是 Trigger 组的话,假如是 Trigger 组的话,triggerName 参数将为 null。参数将为 null。
- jobsPaused方法:当一个或一组 JobDetail 暂停时调用这个方法。
- jobsResumed方法:当一个或一组 Job 从暂停上恢复时调用这个方法。假如是一个 Job 组,jobName 参数将为 null。
- schedulerError方法:在 Scheduler 的正常运行期间产生一个严重错误时调用这个方法。
- schedulerStarted方法:当Scheduler 开启时,调用该方法
- schedulerInStandbyMode方法: 当Scheduler处于StandBy模式时,调用该方法
- schedulerShutdown方法:当Scheduler停止时,调用该方法
- schedulingDataCleared方法:当Scheduler中的数据被清除时,调用该方法。
2. 创建并注册一个SchedulerListener
在scheduler.scheduleJob(jobDetail,trigger)后,scheduler.start()之前,
创建并注册一个SchedulerListener :
scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
移除对应的SchedulerListener :
// scheduler.getListenerManager().removeSchedulerListener(new MySchedulerListener());
欢迎指正,随时修改~