博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Quartz入门指南
阅读量:5976 次
发布时间:2019-06-20

本文共 8473 字,大约阅读时间需要 28 分钟。

Quartz入门指南

看到官网的教程对于新手来说不够全面和连贯,因此结合自己的使用过程写下这个入门指南,用以解惑。本文基于Quartz2.2.2版本。请注意,本文为了易于上手,省略了许多重要的概念,建议阅读

一、安装与配置

下载、解压后,进入lib文件夹,将所有jar文件放入项目指定目录,然后在BuildPath中添加。Jar包共6个,如下所示。

 

Quartz的运行依赖于log4j.xmlquartz.properties这两个配置文件。关于它们的配置方法,请查阅各自官网。我们偷个懒,就用下载包中的吧。在quartz-2.2.2-distribution\quartz-2.2.2\examples\example11目录下找到这俩文件,拷贝到项目指定位置,我是专门新建了个Config文件夹。然后在Eclipse中右击该目录,选择Build Path -> Use as Source Folder,即可。

 

二、Quartz框架

2.1 基本概念

Quartz中最核心的组件是任务、触发器和调度器。任务就是你指定的完成指定业务的执行单元。触发器规定了任务的执行时间、重复周期和频率。调度器将任务和触发器连接起来,它实际上管理着一个线程池和所有的任务和触发器,并进行统一的调度。

2.2 触发器

Quartz包含4种触发器,其中SimpleTrigger CronTrigger可能是最常用的,官方文档中对它们进行了详细的解释(请查看,这里不再详述)。另外两种虽然只在javadoc中有只言片语的介绍,但在特定场景下仍具有不可替代性。

SimpleTrigger :在指定时间激活,然后以指定周期重复指定的次数。比如,14:30分开始,每隔10秒激活一次,重复100次。

CronTrigger:通过一个cron表达式来指定任务激活的年月日星期时分秒,以及重复周期。cron表达式具有一定的语法结构,可以达成非常强大的效果。不受夏令时引起的时钟偏移影响。

CalendarIntervalTrigger 根据一个给定的日历时间进行重复,可以设置启动时间。它可以完成 SimpleTrigger(比如每个月,因为月不是一个确定的秒数)和CronTrigger(比如5个月,因为5个月并不是12个月的公约数)不能完成的一些任务。注意,使用month作为周期单位时,如果起始日期是在某月的最后一天,比如131日,那么下一个激活日在228日,以后所有的激活日都在当月的28日。如果你要严格限制在每月的最后一天激活,那你需要使用cronTrigger。不受夏令时引起的时钟偏移影响。

DailyTimeIntervalTrigger:在给定的时间窗口或指定的星期以秒、分钟、小时为周期进行重复。比如,每天早上8:0011:00之间,每隔72分钟激活;或者每周的周一到周五9:2016:47之间,每隔23分钟激活。注意它的名称Daily,因此重复周期必须在1天以内,不能为星期,月之类的。

2.3 构造器

Quartz提供了构造器风格的API用于构造调度相关的实体。从官方给出的示例代码可以看出,各种实体都是使用构造器来生成的。Quartz的构造器主要有以下几种:

TriggerBuilder:实例化触发器。

JobBuilder:构造JobDetail

ScheduleBuilder:构造调度器,前面介绍的4种触发器分别有一个对应的调度器构造器。

DateBuilder:构造一个日期。

2.3.1 TriggerBuilder

通过其成员函数,能够定义触发器的开始、停止时间、job的各种属性及ScheduleBuilder

具有4个子类,分别是SimpleScheduleBuilderCronScheduleBuilderCalendarIntervalScheduleBuilderDailyTimeIntervalScheduleBuilder,对应4种触发器。在每个子类中,其成员函数均对其特有属性进行配置。比如说,SimpleScheduleBuilder具有()(int count, int hours) 等方法来设置其重复周期和次数。其余方法不再具体介绍,请查阅javadoc。

2.3.2 JobBuilder

用于构造JobDetail,可想而知,它的成员方法均用于设置JobDetail的各种属性,比如descriptiondataMapidentity等等。

2.3.3 ScheduleBuilder

具有4个子类,分别为CalendarIntervalScheduleBuilder, CronScheduleBuilder, DailyTimeIntervalScheduleBuilder, SimpleScheduleBuilder,对应4个触发器,分别用于构造具体的某一种触发器。比如说,构造SimpleTrigger时,需要调用SimpleScheduleBuilder() build()方法;,构造CronTrigger时,需要调用CronScheduleBuilder( cronExpression) build()方法。其中,build()是由父类继承的,用于生成触发器。

2.3.4 DateBuilder

用于根据各种条件来构造一个日期。比如,dateOf(int hour,int minute, int second, int dayOfMonth, int month, int year)atHourOfDay(int atHour)( date)( date, int minuteBase) (int hour, int minute, int second)(int day) 等等。

三、示例代码

 

使用SimpleTrigger的代码如下所示:

public void SimpleTriggerTest() throws Exception {        SchedulerFactory sf = new StdSchedulerFactory();        Scheduler sched = sf.getScheduler();        JobDetail job1 = newJob(SimpleJob.class).withIdentity("job1", "group1")                .build();        Trigger trigger1 = newTrigger()//TriggerBuilder.newTrigger()                .startAt(DateBuilder.dateOf(10, 10, 10, 13, 3, 2016))                .withSchedule(                        simpleSchedule().repeatSecondlyForTotalCount(5, 2))//
TriggerBuilder
withSchedule(ScheduleBuilder
schedBuilder) .build(); Date ft = sched.scheduleJob(job1, trigger1); sched.start(); }

有几个地方需要说明:

1.TriggerBuilder.newTrigger()。这是构造器,由于在头文件中已经使用了”import static org.quartz.TriggerBuilder.newTrigger;”静态引用所以不需要体现类名TriggerBuilder。startAt是它的方法,可以指定触发器的开始时间。

2.withSchedule方法的参数是一个schedBuilder,返回一个TriggerBuilder。

3.repeatSecondlyForTotalCount方法用于设置重复周期和次数,它是由simpleSchedule这个构造器提供的,而不是最终生成的simpleTrigger提供的,simpleTrigger没有相应方法。

完整的示例代码如下:

QuartzDemo.java

 

import static org.quartz.CalendarIntervalScheduleBuilder.calendarIntervalSchedule;import static org.quartz.CronScheduleBuilder.cronSchedule;import static org.quartz.DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule;import static org.quartz.JobBuilder.newJob;import static org.quartz.SimpleScheduleBuilder.simpleSchedule;import static org.quartz.TriggerBuilder.newTrigger;import java.util.Calendar;import java.util.Date;import java.util.HashSet;import java.util.Set;import org.quartz.DateBuilder;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.TimeOfDay;import org.quartz.Trigger;import org.quartz.DateBuilder.IntervalUnit;import org.quartz.impl.StdSchedulerFactory;public class QuartzDemo {    public void CalendarIntervalTriggerTest() throws SchedulerException{        SchedulerFactory sf = new StdSchedulerFactory();        Scheduler sched = sf.getScheduler();        JobDetail job = newJob(SimpleJob.class).withIdentity("job", "group1").build();        //每隔5个月,在指定日期和时间激活任务        Trigger trigger = newTrigger().startAt(DateBuilder.dateOf(10, 10, 10, 13, 3, 2016)).withSchedule(calendarIntervalSchedule().withInterval(5, IntervalUnit.MONTH)).build();        Date ft = sched.scheduleJob(job, trigger);        sched.start();    }        public void CronTriggerTest() throws SchedulerException{        SchedulerFactory sf = new StdSchedulerFactory();        Scheduler sched = sf.getScheduler();        JobDetail job = newJob(SimpleJob.class).withIdentity("job2", "group1").build();        //每个周一到周五,早上8点-11点的整点激活任务,从明天早上9点开始        Trigger trigger = newTrigger().startAt(DateBuilder.tomorrowAt(9, 0, 0)).withIdentity("trigger2", "group1").withSchedule(cronSchedule("* 0 8-11 ? * MON-FRI"))                .build();        Date ft = sched.scheduleJob(job, trigger);        sched.start();    }            public void DailyTimeIntervalTriggerTest() throws SchedulerException{        SchedulerFactory sf = new StdSchedulerFactory();        Scheduler sched = sf.getScheduler();        JobDetail job = newJob(SimpleJob.class).withIdentity("job2", "group1").build();        Set
daysOfWeek = new HashSet
(); daysOfWeek.add(Calendar.SATURDAY); daysOfWeek.add(Calendar.SUNDAY); //每个周末,20点-20点30分,每隔1分钟激活1次 Trigger trigger = newTrigger().startNow().withSchedule(dailyTimeIntervalSchedule().onDaysOfTheWeek(daysOfWeek).withInterval(1, IntervalUnit.MINUTE).withRepeatCount(5).startingDailyAt(new TimeOfDay(20,00)).endingDailyAt(new TimeOfDay(20,30))) .build(); Date ft2 = sched.scheduleJob(job, trigger); sched.start(); } public void SimpleTriggerTest() throws Exception { SchedulerFactory sf = new StdSchedulerFactory(); Scheduler sched = sf.getScheduler(); JobDetail job = newJob(SimpleJob.class).withIdentity("job1", "group1") .build(); //在指定时间,按照指定周期和次数重复激活 Trigger trigger = newTrigger()//TriggerBuilder.newTrigger() .startAt(DateBuilder.dateOf(10, 10, 10, 13, 3, 2016)) .withSchedule( simpleSchedule().repeatSecondlyForTotalCount(5, 2))//
TriggerBuilder
withSchedule(ScheduleBuilder
schedBuilder) .build(); Date ft = sched.scheduleJob(job, trigger); sched.start(); } public static void main(String[] args) throws Exception { QuartzDemo example = new QuartzDemo(); //example.SimpleTriggerTest(); //example.DailyTimeIntervalTriggerTest(); //example.CalendarIntervalTriggerTest(); example.CronTriggerTest(); }}

 

 

SimpleJob.java

import java.util.Date;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class SimpleJob implements Job{               public SimpleJob() {    }    public void execute(JobExecutionContext context)        throws JobExecutionException {        System.out.printf("SimpleJob executed at %s%n", new Date());    }}

 

 

 

四、触发器选用实例

到这里,你应该对各种触发器的功能和参数设置方法有了一定的了解,但是仍然建议你看完以下实例,因为有一些你可能没有想到的问题。

4.1 每隔10秒

使用SimpleTrigger 就好。

4.2 每隔90分钟

使用SimpleTriggerCalendarIntervalTrigger都可以。

4.3 每隔1天

使用CalendarIntervalTrigger CronTrigger。不建议使用SimpleTrigger ,因为夏令时的存在可能会使今天14点的24小时以后是明天的13点或者15点。

4.4 每隔2天

使用CalendarIntervalTrigger。不建议使用SimpleTrigger,原因如上。也不建议使用CronTrigger。试想一下,你的CronExpress的“日”这一位可能会写成“2/2”这样,表示每月的2号开始,每个2天。那么在7月的30号激活后,下一次激活是在8月的2号,这个间隔就是3天而不是2天(7月有31天)。

4.5 每隔1周

使用CronTrigger或者CalendarIntervalTrigger都可以。

4.6 每隔2周

与“2天”同样的原因,使用CronTrigger会有问题,因此建议使用CalendarIntervalTrigger

4.7 每隔1个月

使用CronTriggerCalendarIntervalTrigger

4.8 每隔5个月

使用CalendarIntervalTrigger。与“2天”同样的原因,使用CronTrigger会有问题。试想一下,你的CronExpress的“月”这一位可能会写成“3/5”这样,那么8月激活后,下一个激活点在第二年3月,这个间隔就成了7个月。

五、参考资料

 

转载于:https://www.cnblogs.com/pzy4447/p/5272133.html

你可能感兴趣的文章
软件测试(四)
查看>>
记一次web项目总结
查看>>
Android中的像素单位详解( dp 、 sp 、 px 、 in 、 pt 、 mm )
查看>>
IIS服务无法启动的小实验之MachineKeys文件夹
查看>>
SQL Server 2008 系列简介
查看>>
C++模板实现动态顺序表(更深层次的深浅拷贝)与基于顺序表的简单栈的实现...
查看>>
树莓派raspberry pi配置无线路由器AP
查看>>
【转载】使用WIN32API获取打印机
查看>>
STORM_0002_在做好的zookeeper集群上搭建storm的开发环境
查看>>
Java命名规则
查看>>
C#中发起GET和POST请求的方法
查看>>
《Python从小白到大牛》第7章 运算符
查看>>
博科:毫不迟疑地入软件网络时代
查看>>
玩转开放式虚拟格式,实战迁移虚拟机到vSphere 5
查看>>
轻松实现远程批量拷贝文件脚本(女学生作品)
查看>>
Nmap在pentest box中的扫描及应用
查看>>
测试组合索引
查看>>
四、物理优化(2)索引视图
查看>>
【沟通之道】头脑风暴-女人的心思你别猜
查看>>
redux-form(V7.4.2)笔记(一)
查看>>