目录
概述
Quartz API核心接口
- Scheduler (调度器)
- Job (作业)通过Scheduler执行任务,需要实现的接口
- JobDetail (作业实例)Job类的实例
- Trigger (触发器)触发Job的执行
- JobBuilder 定义和创建JobDetail实例的接口
- TriggerBuilder 定义和创建Trigger实例的接口
Job, Trigger非常容易使用,但是它包含了大量的自定义选项,你需要了解它们才能完全使用Quartz。并且,Trigger本身有很多不同的实现,你需要根据具体情况进行选择。
触发器Trigger基本属性
getKey 获取触发器key值,唯一标识
getJobKey 获取作业key
getCalendarName 获取日历名称
getJobDataMap 获取作业数据map
getPriority 获取优先级
mayFireAgain 是否重复执行
getStartTime 开始生效时间
getEndTime 结束生效时间
getNextFireTime 下一次执行时间
getPreviousFireTime 上一次执行时间
getFireTimeAfter(Date afterTime) 获取某个时间后的运行时间
getFinalFireTime 获取最后执行时间
getMisfireInstruction 获取失败策略
getTriggerBuilder 获取触发器构造者
getScheduleBuilder 获取调度器构造者
//失败策略
MISFIRE_INSTRUCTION_SMART_POLICY 智能
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICE 忽略
所有Trigger都有TriggerKey属性用于跟踪唯一标识,Trigger还有另一些通用的其他属性,这些通用属性可以在你定义Trigger的时候使用TriggerBuilder进行设置。
Priority
有时候,当有多个Trigger(或者在Quartz线程池中有多个工作线程),Quartz可能没有足够的资源同时触发所有触发器上的任务。在这种情况下,你可能想控制你的哪个Trigger将会在Quartz工作线程中第一个被触发。为了满足这个需求,你可以设置Trigger的priority属性。如果有N个Trigger同时被触发,而当时只有Z个工作线程,那么前Z个prority最高的Trigger将会被触发。如果没有设置这个属性,默认值是5。这个属性接受所有整数,正数和负数都合法。
misfire 错过触发机制
Trigger上的另一个很重要的属性是"错过触发策略"。当调度器停止或在Quartz线程池中没有可用的线程可以执行任务的时候,就有可能造成错过触发。
不同的Trigger类型有它们各自不同的错过触发策略。默认情况下,使用"smart policy"策略,这是基于Trigger类型和配置的动态行为。
当调度器启动的时候,它会检索是否有trigger错过触发,然后将基于它们独立配置的错过触发策略进行更新。当你再自己的项目中使用Quartz的时候,你需要熟悉你使用的trigger类型的错过触发策略,在它们的JavaDoc中都有详细说明。
Calendar
Quartz Calendar对象可以在定义Trigger的时候关联到Trigger,并保存在调度器中。
使用Calendar可以很方便地在触发周期内去除某些时间。例如,你可以创建一个trigger,并设置在每个工作日的上午9:30被触发,然后可以添加Calendar来去除所有的节假日。Calendar可以是任何实现Calendar接口的可序列化对象。
package org.quartz;
public interface Calendar {
public boolean isTimeIncluded(long timeStamp);
public long getNextIncludedTime(long timeStamp);
}
Calendars必须实例化并通过addCalendar方法注册到调度器。如果你使用HolidayCalendar,实例化后可以调用addExcludeDate(Date date)方法在运行周期中去除某些日期。相同的Calendar可以由多个Trigger使用。
HolidayCalendar cal = new HolidayCalendar();
cal.addExcludedDate(someDate);
cal.addExcludedDate(anotherDate);
sched.addCalendar("holidays", cal, false);
Trigger t = new Trigger().withIdentity("trigger1")
.forJob("job1")
.withSchedule(dailyAtHourAndMinute(9, 30)) // 每日9点30分
.modifiedByCalendar("holidays")
.build();
sched.scheduleJob(t);
sched.start();
上面的代码创建了每日触发的Trigger,在设置的calendar周期内的触发将会被忽略。org.quartz.impl.calendar包中还有更多的Calendar实现可以满足你的需求。
调度器构造者 ScheduleBuilder
//用于创建各个调度器
ScheduleBuilder (org.quartz)
|-CalendarIntervalScheduleBuilder (org.quartz)
|-DailyTimeIntervalScheduleBuilder (org.quartz)
|-SimpleScheduleBuilder (org.quartz)
|-CronScheduleBuilder (org.quartz)
private TriggerBuilder() 构造函数私有
public static TriggerBuilder<Trigger> newTrigger() 创建一个构造者
build() 创建触发器
// 根据name和默认的group创建trigger的key
public TriggerBuilder<T> withIdentity(String name)
public Triggerbuilder<T> withIdentity(String name, String group)
public TriggerBuilder<T> withIdentity(TriggerKey triggerKey)
//描述
public TriggerBuilder<T> withDescription(String description)
//优先级
public TriggerBuilder<T> withPriority(int priority)
//日期
public TriggerBuilder<T> modifiedByCalendar(String calName)
//立即执行
public TriggerBuilder<T> startNow()
//结束生效时间
public TriggerBuilder<T> endAt(Date triggerEndTime)
//调度器
public <SBT extends T> TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> schedBuilder)
//设置作业
public TriggerBuilder<T> forJob(JobKey keyOfJobToFire)
public TriggerBuilder<T> forJob(String jobName)
public TriggerBuilder<T> forJob(String jobName, String groupName)
public TriggerBuilder<T> forJob(JobDetail jobDetail)
usingJobData(----, ----) 设置作业内容
简单的调度器创建者
//构造函数私有化
protected SimpleScheduleBuilder()
//获取简单调度器
public static SimpleScheduleBuilder simpleSchedule()
/***********************/
// 1分钟执行(一直执行)
public static SimpleScheduleBuilder repeatMinutelyForever()
//每隔几分钟执行(一直执行)
public static SimpleScheduleBuilder repeatMinutelyForever(int minutes)
// 1秒执行(一直执行)
public static SimpleScheduleBuilder repeatSecondlyForever()
//每隔几秒钟执行(一直执行)
public static SimpleScheduleBuilder repeatSecondlyForever(int seconds)
// 1小时执行(一直执行)
public static SimpleScheduleBuilder repeatHourlyForever()
//每隔几小时钟执行(一直执行)
public static SimpleScheduleBuilder repeatHourlyForever(int hours)
/***********************/
//间隔时间为1分钟,总的执行次数为count
public static SimpleScheduleBuilder repeatMinutelyForTotalCount(int count)
//间隔时间为几分钟,总的执行次数为count .............
public static SimpleScheduleBuilder repeatMinutelyForTotalCount(int count, int minutes)
public static SimpleScheduleBuilder repeatSecondlyForTotalCount(int count)
public static SimpleScheduleBuilder repeatSecondlyForTotalCount(int count, int seconds)
public static SimpleScheduleBuilder repeatHourlyForTotalCount(int count)
public static SimpleScheduleBuilder repeatHourlyForTotalCount(int count, int hours)
/***********************/
public MutableTrigger build() 创建一个Trigger
/***********************/
// 几秒钟重复执行
public SimpleScheduleBuilder withIntervalInMilliseconds(long intervalInMillis)
public SimpleScheduleBuilder withIntervalInSeconds(int intervalInSeconds)
public SimpleScheduleBuilder withIntervalInMinutes(int intervalInMinutes)
public SimpleScheduleBuilder withIntervalInHours(int intervalInHours)
/***********************/
// 重复执行册数
public SimpleScheduleBuilder withRepeatCount(int triggerRepeatCount)
/***********************/
//以错过的第一个频率时间立刻开始执行
//重做错过的所有频率周期后
//当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行
public SimpleScheduleBuilder withMisfireHandlingInstructionIgnoreMisfires()
//以当前时间为触发频率立即触发执行
//执行至FinalTIme的剩余周期次数
//以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
//调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
public SimpleScheduleBuilder withMisfireHandlingInstructionFireNow()
//不触发立即执行
//等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
//以startTime为基准计算周期频率,并得到FinalTime
//即使中间出现pause,resume以后保持FinalTime时间不变
public SimpleScheduleBuilder withMisfireHandlingInstructionNextWithExistingCount()
//不触发立即执行
//等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
//以startTime为基准计算周期频率,并得到FinalTime
//即使中间出现pause,resume以后保持FinalTime时间不变
public SimpleScheduleBuilder withMisfireHandlingInstructionNextWithRemainingCount()
//以当前时间为触发频率立即触发执行
//执行至FinalTIme的剩余周期次数
//以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
//调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
public SimpleScheduleBuilder withMisfireHandlingInstructionNowWithExistingCount()
//以当前时间为触发频率立即触发执行
//执行至FinalTIme的剩余周期次数
//以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
public SimpleScheduleBuilder withMisfireHandlingInstructionNowWithRemainingCount()
interval 时间间隔
repeatCount 重复时间
misfireInstruction
CronScheduleBuilder
// 构造函数私有化
protected CronScheduleBuilder(CronExpression cronExpression)、
public MutableTrigger build()
// 根据cron表达式建造
public static CronScheduleBuilder cronSchedule(String cronExpression)
// 核查表达式是否正确
public static CronScheduleBuilder cronScheduleNonvalidatedExpression(String cronExpression) throws ParseException
//表达式异常
cronScheduleNoParseException
// 利用CronExpression建造
public static CronScheduleBuilder cronSchedule(CronExpression cronExpression)
//每天在指定的时间执行,根据这个调度创建一个cron表达式
public static CronScheduleBuilder dailyAtHourAndMinute(int hour, int minute)
// 通过`分钟`、`小时`、`周`创建一个CronScheduleBuilder实例,即在某一天的给定时刻
// (通过`分钟`、`小时`指定)执行,,而天数由`周`确定,如果“周二、周四的10:05“等;
public static CronScheduleBuilder atHourAndMinuteOnGivenDaysOfWeek(int hour, int minute, Integer... daysOfWeek)
//调度计划:每周的某一天,在指定的时间(小时和分钟)执行
public static CronScheduleBuilder weeklyOnDayAndHourAndMinute(int dayOfWeek, int hour, int minute)
//调度计划:每月的某一天,在指定的时间(小时和分钟)执行
public static CronScheduleBuilder monthlyOnDayAndHourAndMinute(int dayOfMonth, int hour, int minute)
//设置时区
public CronScheduleBuilder inTimeZone(TimeZone timezone)
// 设置处理办法
public CronScheduleBuilder withMisfireHandlingInstructionIgnoreMisfires()
public CronScheduleBuilder withMisfireHandlingInstructionDoNothing()
public CronScheduleBuilder withMisfireHandlingInstructionFireAndProceed()
cronExpression
misfireInstruction
CalendarIntervalScheduleBuilder
CalendarIntervalScheduleBuilder
calendarIntervalSchedule
build
// 和DailyTimeIntervalScheduleBuilder差不多
public CalendarIntervalScheduleBuilder withInterval(int timeInterval, IntervalUnit unit)
withIntervalInSeconds
withIntervalInMinutes
withIntervalInHours
withIntervalInDays
withIntervalInWeeks
withIntervalInMonths
withIntervalInYears
withMisfireHandlingInstructionIgnoreMisfires
withMisfireHandlingInstructionDoNothing
withMisfireHandlingInstructionFireAndProceed
inTimeZone
preserveHourOfDayAcrossDaylightSavings
skipDayIfHourDoesNotExist
validateInterval
interval
intervalUnit
misfireInstruction
timeZone
preserveHourOfDayAcrossDaylightSavings
skipDayIfHourDoesNotExist
DailyTimeIntervalScheduleBuilder
DailyTimeIntervalScheduleBuilder()
dailyTimeIntervalSchedule()
build()
withInterval(int timeInterval, IntervalUnit unit) //执行时间间隔触发执行,unit时间单位
withIntervalInSeconds(int intervalInSeconds) //秒
withIntervalInMinutes(int intervalInMinutes) //分钟
withIntervalInHours(int intervalInHours) //小时
// 周几执行
onDaysOfTheWeek(Set<Integer> onDaysOfWeek)
onDaysOfTheWeek(Integer... onDaysOfWeek)
onMondayThroughFriday()
onSaturdayAndSunday()
onEveryDay()
startingDailyAt(TimeOfDay timeOfDay) // 开始触发时间
endingDailyAt(TimeOfDay timeOfDay) //结束时间
endingDailyAfterCount(int count)
withMisfireHandlingInstructionIgnoreMisfires()
withMisfireHandlingInstructionDoNothing()
withMisfireHandlingInstructionFireAndProceed()
//重复次数
withRepeatCount()
validateInterval()
// 常量等
interval
intervalUnit
daysOfWeek
startTimeOfDay
endTimeOfDay
repeatCount
misfireInstruction
ALL_DAYS_OF_THE_WEEK
MONDAY_THROUGH_FRIDAY
SATURDAY_AND_SUNDAY
触发器Trigger实现类
常用的触发器有以下四个:
SimpleTrigger 简单触发器
CalendarIntervalTrigger 日历触发器
DailyTimeIntervalTrigger 日期触发器
CronTrigger Cron表达式触发器
SimpleTrigger
指定从某一个时间开始,以一定的时间间隔(单位是毫秒)执行的任务。它适合的任务类似于: 9:00开始,每隔1小时,每隔几分钟,每隔几秒钟执行一次。
它的属性有:
repeatInterval:重复间隔
repeatCount:重复次数。实际执行次数是repeatCount + 1,因为在startTime的时候会执行一次。
import org.quartz.*;
import java.util.Date;
public class SimpleTriggerMain {
public static void main(String[] args) throws SchedulerException {
SchedulerFactory factory = new org.quartz.impl.StdSchedulerFactory();
//调度器
Scheduler sched = factory.getScheduler();
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 在当前时间15秒后执行
Date startTime = DateBuilder.nextGivenSecondDate(new Date(), 15);
//创建一个SimpleTrigger实例,指定所属组及名称,设置调度规则:当前时间15秒后开始,每10秒运行一次,共5次
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.startAt(startTime).withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(5)
).build();
sched.scheduleJob(job, trigger);
sched.start();
}
}
CalendarIntervalTrigger
指定从某一个时间开始,以一定的时间间隔执行的任务。不同于SimpleTrigger只支持毫秒单位的时间间隔,CalendarIntervalTrigger支持的间隔单位有秒、分钟、小时、天、月、年、星期。
它适合的任务类似于9:00开始,以后每周执行一次。它的属性有:
interval:执行间隔
intervalUnit:执行间隔单位(秒、分、小时、天、月、年、星期)
//每两秒执行
CalendarIntervalTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(
CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withInterval(2, DateBuilder.IntervalUnit.SECOND)).build();
DailyTimeIntervalTrigger
指定每天的某个时间段内,以一定的时间间隔执行任务。并且它可以支持指定星期。
它支持的任务类似于:每天9:00到18:00,每隔70秒执行一次,。并且只要周一至周五执行。它的属性有:
startTimeOfDay:每天开始时间
endTimeOfDay:每天结束时间
daysOfWeek:周几执行
interval:执行间隔
intervalUnit:执行间隔的单位(秒、分、小时、天、月、年、星期)
repeatUnit:重复次数
DailyTimeIntervalTrigger trigger = dailyTimeIntervalSchedule().
.startingDailyAt(TimeOfDay.hourAndMinuteOfDay(9, 0))
.endingDailyAt(TimeOfDay.hourAndMinuteOfDay(18, 0))
.onDaysOfWeek(MONDAY, TUESDAY, WEDSDAY, THURSDAY, FRIDAY)
.withRepeatCount(100)
.build();
//每隔2秒执行
DailyTimeIntervalTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(
DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule().withInterval(2, DateBuilder.IntervalUnit.SECOND)
).build();
CronTrigger
适合于更复杂的任务,它支持类似于Linux Cron的语法。基本上覆盖了以上三个Trigger的绝大部分能力。CronTrigger允许设定非常复杂的触发时间表,它的属性只有:cron表达式。
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(
CronScheduleBuilder.cronSchedule("/2 * * * * ?")
).build();