package com.zchen.study.quartz;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class SimpleQuartzJob implements Job{
public SimpleQuartzJob() {
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("In SimpleQuartzJob - executing its JOB at "
+ new Date() + " by " + context.getTrigger().getName());
}
}
这个类用一条非常简单的输出语句实现了Job接口的execute(JobExecutionContext context) 方法,这个方法可以包含想要执行的任何代码。下面,我们通过SimpleTrigger对SimpleJob进行调度:
请注意,execute 方法接受一个 JobExecutionContext
对象作为参数。这个对象提供了作业实例的运行时上下文。特别地,它提供了对调度器和触发器的访问,这两者协作来启动作业以及作业的 JobDetail
对象的执行。Quartz 通过把作业的状态放在 JobDetail
对象中并让 JobDetail
构造函数启动一个作业的实例,分离了作业的执行和作业周围的状态。JobDetail
对象储存作业的侦听器、群组、数据映射、描述以及作业的其他属性。
package com.zchen.study.quartz;
import java.util.Date;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;
public class SimpleTriggerRunner {
public static void main(String[] args) {
try {
new SimpleTriggerRunner().task();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public void task() throws SchedulerException
{
// current time
long ctime = System.currentTimeMillis();
// ①创建一个JobDetail实例,指定SimpleJob
JobDetail jobDetail = new JobDetail("jobDetail-s1", "jobDetailGroup-s1", SimpleQuartzJob.class);
// ②通过SimpleTrigger定义调度规则:马上启动,每2秒运行一次,共运行100次
SimpleTrigger simpleTrigger = new SimpleTrigger("simpleTrigger", "triggerGroup-s1");
// set its start up time
simpleTrigger.setStartTime(new Date(ctime));
// set the interval, how often the job should run (10 seconds here)
simpleTrigger.setRepeatInterval(2000);
// set the number of execution of this job, set to 10 times.
// It will run 10 time and exhaust.
simpleTrigger.setRepeatCount(100);
/**set the ending time of this job.
We set it for 60 seconds from its startup time here
Even if we set its repeat count to 10,
this will stop its process after 6 repeats as it gets it endtime by then.
simpleTrigger.setEndTime(new Date(ctime + 60000L));
set priority of trigger. If not set, the default is 5
simpleTrigger.setPriority(10);*/
// Initiate a Schedule Factory
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
//③通过SchedulerFactory获取一个调度器实例
Scheduler scheduler = schedulerFactory.getScheduler();
// ④ 注册并进行调度
scheduler.scheduleJob(jobDetail, simpleTrigger);
// ⑤调度启动
scheduler.start();
}
}
首先在①处通过JobDetail封装SimpleJob,同时指定Job在Scheduler中所属组及名称,这里,组名为jGroup1,而名称为job1_1。
在②处创建一个SimpleTrigger实例,指定该Trigger在Scheduler中所属组及名称。接着设置调度的时间规则。
最后,需要创建Scheduler实例,并将JobDetail和Trigger实例注册到Scheduler中。这里,我们通过StdSchedulerFactory获取一个Scheduler实例,并通过scheduleJob(JobDetail jobDetail, Trigger trigger)完成两件事:
1)将JobDetail和Trigger注册到Scheduler中;
2)将Trigger指派给JobDetail,将两者关联起来。
当Scheduler启动后,Trigger将定期触发并执行SimpleJob的execute(JobExecutionContext jobCtx)方法,然后每 10 秒重复一次,直到任务被执行 100 次后停止。
还可以通过SimpleTrigger的setStartTime(java.util.Date startTime)和setEndTime(java.util.Date endTime)指定运行的时间范围,当运行次数和时间范围冲突时,超过时间范围的任务运行不被执行。如可以通过simpleTrigger.setStartTime(new Date(System.currentTimeMillis() + 60000L))指定60秒钟以后开始。
除了通过scheduleJob(jobDetail, simpleTrigger)建立Trigger和JobDetail的关联,还有另外一种关联Trigger和JobDetail的方式:
JobDetail jobDetail = new JobDetail("job1_1","jGroup1", SimpleJob.class);
SimpleTrigger simpleTrigger = new SimpleTrigger("trigger1_1","tgroup1");
…
simpleTrigger.setJobGroup("jGroup1");①-1:指定关联的Job组名
simpleTrigger.setJobName("job1_1");①-2:指定关联的Job名称
scheduler.addJob(jobDetail, true);② 注册JobDetail
scheduler.scheduleJob(simpleTrigger);③ 注册指定了关联JobDetail的Trigger
在这种方式中,Trigger通过指定Job所属组及Job名称,然后使用Scheduler的scheduleJob(Trigger trigger)方法注册Trigger。有两个值得注意的地方:
通过这种方式注册的Trigger实例必须已经指定Job组和Job名称,否则调用注册Trigger的方法将抛出异常;
引用的JobDetail对象必须已经存在于Scheduler中。也即,代码中①、②和③的先后顺序不能互换。
在构造Trigger实例时,可以考虑使用org.quartz.TriggerUtils工具类,该工具类不但提供了众多获取特定时间的方法,还拥有众多获取常见Trigger的方法,如makeSecondlyTrigger(String trigName)方法将创建一个每秒执行一次的Trigger,而makeWeeklyTrigger(String trigName, int dayOfWeek, int hour, int minute)将创建一个每星期某一特定时间点执行一次的Trigger。而getEvenMinuteDate(Date date)方法将返回某一时间点一分钟以后的时间。