Quartz入门指南
看到官网的教程对于新手来说不够全面和连贯,因此结合自己的使用过程写下这个入门指南,用以解惑。本文基于Quartz2.2.2版本。请注意,本文为了易于上手,省略了许多重要的概念,建议阅读Quartz2.2.x官方教程。
下载、解压后,进入lib文件夹,将所有jar文件放入项目指定目录,然后在BuildPath中添加。Jar包共6个,如下所示。
Quartz的运行依赖于log4j.xml和quartz.properties这两个配置文件。关于它们的配置方法,请查阅各自官网。我们偷个懒,就用下载包中的吧。在”quartz-2.2.2-distribution\quartz-2.2.2\examples\example11”目录下找到这俩文件,拷贝到项目指定位置,我是专门新建了个Config文件夹。然后在Eclipse中右击该目录,选择”Build Path -> Use as Source Folder”,即可。
Quartz中最核心的组件是任务、触发器和调度器。任务就是你指定的完成指定业务的执行单元。触发器规定了任务的执行时间、重复周期和频率。调度器将任务和触发器连接起来,它实际上管理着一个线程池和所有的任务和触发器,并进行统一的调度。
Quartz包含4种触发器,其中SimpleTrigger 和CronTrigger可能是最常用的,官方文档中对它们进行了详细的解释(请查看Quartz2.2.x官方教程,这里不再详述)。另外两种虽然只在javadoc中有只言片语的介绍,但在特定场景下仍具有不可替代性。
SimpleTrigger :在指定时间激活,然后以指定周期重复指定的次数。比如,14:30分开始,每隔10秒激活一次,重复100次。
CronTrigger:通过一个cron表达式来指定任务激活的年月日星期时分秒,以及重复周期。cron表达式具有一定的语法结构,可以达成非常强大的效果。不受夏令时引起的时钟偏移影响。
CalendarIntervalTrigger 根据一个给定的日历时间进行重复,可以设置启动时间。它可以完成 SimpleTrigger(比如每个月,因为月不是一个确定的秒数)和CronTrigger(比如5个月,因为5个月并不是12个月的公约数)不能完成的一些任务。注意,使用month作为周期单位时,如果起始日期是在某月的最后一天,比如1月31日,那么下一个激活日在2月28日,以后所有的激活日都在当月的28日。如果你要严格限制在每月的最后一天激活,那你需要使用cronTrigger。不受夏令时引起的时钟偏移影响。
DailyTimeIntervalTrigger:在给定的时间窗口或指定的星期以秒、分钟、小时为周期进行重复。比如,每天早上8:00到11:00之间,每隔72分钟激活;或者每周的周一到周五9:20到16:47之间,每隔23分钟激活。
Quartz提供了构造器风格的API用于构造调度相关的实体。从官方给出的示例代码可以看出,各种实体都是使用构造器来生成的。Quartz中的构造器主要有以下几种:
TriggerBuilder:实例化触发器。
JobBuilder:构造JobDetail。
ScheduleBuilder:构造调度器,前面介绍的4种触发器分别有一个对应的调度器构造器。
DateBuilder:构造一个日期。
通过其成员函数,能够定义触发器的开始、停止时间、job的各种属性及ScheduleBuilder。
具有4个子类,分别是SimpleScheduleBuilder,CronScheduleBuilder,CalendarIntervalScheduleBuilder,DailyTimeIntervalScheduleBuilder,对应4种触发器。在每个子类中,其成员函数均对其特有属性进行配置。比如说,SimpleScheduleBuilder具有repeatForever(),repeatHourlyForTotalCount(int count, int hours) 等方法来设置其重复周期和次数。其余方法不再具体介绍,请查阅javadoc。
用于构造JobDetail,可想而知,它的成员方法均用于设置JobDetail的各种属性,比如description,dataMap,identity等等。
具有4个子类,分别为CalendarIntervalScheduleBuilder, CronScheduleBuilder, DailyTimeIntervalScheduleBuilder, SimpleScheduleBuilder,对应4个触发器,分别用于构造具体的某一种触发器。比如说,构造SimpleTrigger时,需要调用SimpleScheduleBuilder的simpleSchedule() 和build()方法;,构造CronTrigger时,需要调用CronScheduleBuilder的cronSchedule(String cronExpression) 和build()方法。其中,build()是由父类继承的,用于生成触发器。
用于根据各种条件来构造一个日期。比如,dateOf(int hour,int minute, int second, int dayOfMonth, int month, int year),atHourOfDay(int atHour),evenHourDate(Date date),nextGivenMinuteDate(Date date, int minuteBase) ,tomorrowAt(int hour, int minute, int second),validateDayOfMonth(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))//<SBT extends T> TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> 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没有相应方法。
到这里,你应该对各种触发器的功能和参数设置方法有了一定的了解,但是仍然建议你看完以下实例,因为有一些你可能没有想到的问题。
使用SimpleTrigger 就好。
使用SimpleTrigger或CalendarIntervalTrigger都可以。
使用CalendarIntervalTrigger 或CronTrigger。不建议使用SimpleTrigger ,因为夏令时的存在可能会使今天14点的24小时以后是明天的13点或者15点。
使用CalendarIntervalTrigger。不建议使用SimpleTrigger,原因如上。也不建议使用CronTrigger。试想一下,你的CronExpress的“日”这一位可能会写成“2/2”这样,表示每月的2号开始,每个2天。那么在7月的30号激活后,下一次激活是在8月的2号,这个间隔就是3天而不是2天(7月有31天)。
使用CronTrigger或者CalendarIntervalTrigger都可以。
与“2天”同样的原因,使用CronTrigger会有问题,因此建议使用CalendarIntervalTrigger。
使用CronTrigger或CalendarIntervalTrigger。
使用CalendarIntervalTrigger。与“2天”同样的原因,使用CronTrigger会有问题。试想一下,你的CronExpress的“月”这一位可能会写成“3/5”这样,那么8月激活后,下一个激活点在第二年3月,这个间隔就成了7个月。