Job与JobDetail是Quartz用来定义具体任务的,而Trigger则是用来定义任务如何执行的。Quartz提供了Trigger接口来定义公共属性,使用TriggerBuilder可以创建具体类型的Trigger;最常见的两种Trigger分别是SimpleTrigger、CronTrigger。重点说一下Trigger。
package org.quartz;
public interface Calendar {
public boolean isTimeIncluded(long timeStamp);
public long getNextIncludedTime(long timeStamp);
}
这两个方法都是精确到毫秒的;如果只是排除以天为单位的时间,可以使用HolidayCalendar。
Calendars必须实例化,然后通过Scheduler的addCalendar()方法注册。Calendars可以重复使用,如下代码:
Trigger trigger1 = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "test")
.startAt(DateBuilder.futureDate(3, IntervalUnit.SECOND))
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(5000)
.withIntervalInSeconds(5)
.withRepeatCount(5))
.modifiedByCalendar("holidayCalendar")
.build();
Trigger trigger2 = TriggerBuilder.newTrigger()
.withIdentity("trigger2", "test")
.startAt(DateBuilder.futureDate(3, IntervalUnit.SECOND))
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(5000)
.withIntervalInSeconds(5)
.withRepeatCount(5))
.modifiedByCalendar("holidayCalendar")
.build();
下面来看SimpleTrigger。通过之前的例子可以看到如何创建Trigger,首先通过TriggerBuilder.newTrigger()方法建立一个TriggerBuilder对象,然后通过withSchedule()方法指定了SimpleScheduleBuilder,最后build()方法构建出了SimpleTrigger对象。
SimpleTrigger很简单,之前例子中创建的都是SimpleTrigger,任务启动后每隔5s运行一次,总共运行5次。Quartz提供了DateBuilder工具类来方便设置时间,里面提供了很多方法,如上面Trigger2设置的启动时间就是3秒后启动任务。
CronTrigger使用cron表达式来设置触发时间。CronTrigger创建方式:
Trigger trigger3 = TriggerBuilder.newTrigger()
.withIdentity("cron trigger", "test")
.withSchedule(
//每5秒执行一次
CronScheduleBuilder.cronSchedule("0/5 * * ? * *")
).build();
二、简单案例
编写任务调度工具类:
package com.utils;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
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;
/**
* 任务调度公共类
*
* @author iaiai QQ:176291935
* @remark
* @time 2015-3-23下午3:04:12
*/
public class QuartzUtil {
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(QuartzUtil.class);//日志
/**
* 添加任务的方法
*
* @param jobName 任务名
* @param triggerName 触发器名
* @param jobClass 执行任务的类
* @param seconds 间隔时间
* @throws SchedulerException
*/
public static void addJob(String jobName, String triggerName, Class extends Job> jobClass, int seconds) throws SchedulerException {
log.info("==================initialization=================");
//创建一个SchedulerFactory工厂实例
SchedulerFactory sf = new StdSchedulerFactory();
//通过SchedulerFactory构建Scheduler对象
Scheduler sche = sf.getScheduler();
log.info("===================initialize finshed===================");
log.info("==============add the Job to Scheduler==================");
//用于描叙Job实现类及其他的一些静态信息,构建一个作业实例
JobDetail jobDetail = JobBuilder.newJob(jobClass)
.withIdentity(jobName, JOB_GROUP_NAME)
.build();
//构建一个触发器,规定触发的规则
Trigger trigger = TriggerBuilder.newTrigger()//创建一个新的TriggerBuilder来规范一个触发器
.withIdentity(triggerName, TRIGGER_GROUP_NAME)//给触发器起一个名字和组名
.startNow()//立即执行
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(seconds)//时间间隔 单位:秒
.repeatForever()//一直执行
//CronTrigger使用cron表达式来设置触发时间。CronTrigger创建方式:
//CronScheduleBuilder.cronSchedule("0 53 19 ? * *") [[秒] [分] [小时] [日] [月] [周] [年] 当前为每天下午7点53执行
)
.build();//产生触发器
//向Scheduler中添加job任务和trigger触发器
sche.scheduleJob(jobDetail, trigger);
//启动
sche.start();
}
}
编写实际任务执行类,执行实际的业务操作:
package com.utils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
public class QuartzJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("this is the job execute method" + new Date());
}
}
编写测试类:
package com.test;
import com.utils.QuartzJob;
import com.utils.QuartzUtil;
import org.quartz.*;
public class jobTest {
public static void main(String[] args) {
try {
QuartzUtil.addJob("job1", "trigger1", QuartzJob.class, 2);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
三、附录:CronExpression表达式
格式:[秒] [分] [时] [每月的第几日] [月] [每周的第几日] [年]
字段名 | 必须的 | 允许值 | 允许的特殊字符 |
---|---|---|---|
Seconds | YES | 0-59 | , - * / |
Minutes | YES | 0-59 | , - * / |
Hours | YES | 0-23 | , - * / |
Day of month | YES | 1-31 | , - * ? / L W |
Month | YES | 1-12 or JAN-DEC | , - * / |
Day of week | YES | 1-7 or SUN-SAT | , - * ? / L # |
Year | NO | empty, 1970-2099 | , - * / |
特殊字符说明:
字符 | 含义 |
---|---|
* |
用于 指定字段中的所有值 。比如:* 在分钟中表示 每一分钟 。 |
? |
用于 指定日期中的某一天 ,或是 星期中的某一个星期 。 |
- |
用于 指定范围 。比如:10-12 在小时中表示 10 点,11 点,12 点 。 |
, |
用于 指定额外的值 。比如:MON,WED,FRI 在日期中表示 星期一, 星期三, 星期五 。 |
/ |
用于 指定增量 。比如:0/15 在秒中表示 0 秒, 15 秒, 30 秒, 45 秒 。5/15 在秒中表示 5 秒,20 秒,35 秒,50 秒 。 |
L |
在两个字段中拥有不同的含义。比如:L 在日期(Day of month)表示 某月的最后一天 。在星期(Day of week)只表示 7 或 SAT 。但是,值L 在星期(Day of week)中表示 某月的最后一个星期几 。 比如:6L 表示 某月的最后一个星期五 。也可以在日期(Day of month)中指定一个偏移量(从该月的最后一天开始).比如:L-3 表示 某月的倒数第三天 。 |
W |
用于指定工作日(星期一到星期五)比如:15W 在日期中表示 到 15 号的最近一个工作日 。如果第十五号是周六, 那么触发器的触发在 第十四号星期五 。如果第十五号是星期日,触发器的触发在 第十六号周一 。如果第十五是星期二,那么它就会工作开始在 第十五号周二 。然而,如果指定 1W 并且第一号是星期六,那么触发器的触发在第三号周一,因为它不会 "jump" 过一个月的日子的边界。 |
L 和 W |
可以在日期(day-of-month)合使用,表示 月份的最后一个工作日 。 |
# |
用于 指定月份中的第几天 。比如:6#3 表示 月份的第三个星期五 (day 6 = Friday and "#3" = the 3rd one in the month)。其它的有,2#1 表示 月份第一个星期一 。4#5 表示 月份第五个星期三 。注意: 如果只是指定 #5 ,则触发器在月份中不会触发。 |
注意:字符不区分大小写,MON
和 mon
相同。
表达式 | 含义 |
---|---|
0 0 12 * * ? |
每天中午 12 点 |
0 15 10 ? * * |
每天上午 10 点 15 分 |
0 15 10 * * ? |
每天上午 10 点 15 分 |
0 15 10 * * ? * |
每天上午 10 点 15 分 |
0 15 10 * * ? 2005 |
在 2005 年里的每天上午 10 点 15 分 |
0 * 14 * * ? |
每天下午 2 点到下午 2 点 59 分的每一分钟 |
0 0/5 14 * * ? |
每天下午 2 点到 2 点 55 分每隔 5 分钟 |
0 0/5 14,18 * * ? |
每天下午 2 点到 2 点 55 分, 下午 6 点到 6 点 55 分, 每隔 5 分钟 |
0 0-5 14 * * ? |
每天下午 2 点到 2 点 5 分的每一分钟 |
0 10,44 14 ? 3 WED |
3 月每周三的下午 2 点 10 分和下午 2 点 44 分 |
0 15 10 ? * MON-FRI |
每周一到周五的上午 10 点 15 分 |
0 15 10 15 * ? |
每月 15 号的上午 10 点 15 分 |
0 15 10 L * ? |
每月最后一天的上午 10 点 15 分 |
0 15 10 L-2 * ? |
每月最后两天的上午10点15分 |
0 15 10 ? * 6L |
每月的最后一个星期五的上午 10 点 15 分 |
0 15 10 ? * 6L 2002-2005 |
2002 年到 2005 年每个月的最后一个星期五的上午 10 点 15 分 |
0 15 10 ? * 6#3 |
每月的第三个星期五的上午 10 点 15 分 |
0 0 12 1/5 * ? |
每月的 1 号开始每隔 5 天的中午 12 点 |
0 11 11 11 11 ? |
每年 11 月 11 号上午 11 点 11 分 |