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框架

2.1 基本概念

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

2.2 触发器

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分钟激活。注意它的名称Daily,因此重复周期必须在1天以内,不能为星期,月之类的。

2.3 构造器

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

TriggerBuilder:实例化触发器。

JobBuilder:构造JobDetail。

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

DateBuilder:构造一个日期。

2.3.1 TriggerBuilder

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

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

2.3.2 JobBuilder

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

2.3.3 ScheduleBuilder

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

2.3.4 DateBuilder

用于根据各种条件来构造一个日期。比如,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没有相应方法。

完整的示例代码如下:

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<Integer> daysOfWeek = new HashSet<Integer>();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))//<SBT extends T> TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> 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分钟

使用SimpleTrigger或CalendarIntervalTrigger都可以。

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个月

使用CronTrigger或CalendarIntervalTrigger。

4.8 每隔5个月

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

五、参考资料

Quartz Scheduler Example Programs and Sample Code

Quartz Enterprise Job Scheduler 2.2.1 API

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

Quartz入门指南相关推荐

  1. Quartz.NET快速入门指南

    最近,在工作中遇到了 Quartz.net 这个组件,为了更好的理解项目代码的来龙去脉,于是决定好好的研究一下这个东西.确实是好东西,既然是好东西,我就拿出来分享一下.万丈高楼平地起,我们也从入门开始 ...

  2. 张高兴的 .NET IoT 入门指南:(七)制作一个气象站

    距离上一篇<张高兴的 .NET Core IoT 入门指南>系列博客的发布已经过去 2 年的时间了,2 年的时间 .NET 版本发生了巨大的变化,.NET Core 也已不复存在,因此本系 ...

  3. 入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集-深度学习问题

    入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集 GT_Zhang关注 0.1012019.08.01 18:43:34字数 1,874阅读 795 Hi,欢迎各位来自Paddl ...

  4. Maven入门指南⑦:Maven的生命周期和插件

    Maven入门指南⑦:Maven的生命周期和插件 一个完整的项目构建过程通常包括清理.编译.测试.打包.集成测试.验证.部署等步骤,Maven从中抽取了一套完善的.易扩展的生命周期.Maven的生命周 ...

  5. UE4风格化场景设计入门指南 Stylized Station – The Environment Artist’s Survival Kit

    持续时间13h 1920X1080 .ts 包含项目文件 大小解压后:4.9G 语言:英语+中文字幕(人工校对) 标题:风格化的车站--环境艺术家的生存工具包 信息: 环境艺术很难. 尤其是作为初学者 ...

  6. 游戏风格化角色创建入门指南视频教程

    游戏风格化角色创建入门指南视频教程 时间 33小时 包括项目文件 1920X1080 MP4 语言:英语+中文字幕(根据原英文字幕机译更准确)+原英文字幕 游戏中的风格化角色创建入门指南  百度一下 ...

  7. mongoDB 入门指南、示例

    http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html mongoDB 入门指南.示例 上一篇:简单介绍mongoDB 一.准备工作 ...

  8. 智能合约和区块链技术:入门指南

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 智能合约和区块链技术:入门指南 多年前,在没有数字合约和区块链技术存在的情况下,双方的合约往往以传统的方式进行.在加密货 ...

  9. 数据分析从头学_数据新闻学入门指南:让我们从头开始构建故事

    数据分析从头学 by Mina Demian 由Mina Demian 数据新闻学入门指南:让我们从头开始构建故事 (A Beginner's Guide to Data Journalism: Le ...

最新文章

  1. cefsharp 发送请求服务器_WEB服务器之HTTP协议
  2. 黄铁军、沈向洋、王海峰入选,中国工程院21年院士增选有效候选人名单公布...
  3. Python + Selenium 练习篇 - 获取页面所有邮箱
  4. React Native --网络请求(fetch)
  5. win10使用自带虚拟机没有Hyper-V场景
  6. L1-045. 宇宙无敌大招呼
  7. SAP UI5 aggregation field type
  8. 以编程方式访问Java基本类型的大小
  9. python示例异常处理与程序调试_Python错误处理及代码调试方
  10. 《Java从入门到放弃》框架入门篇:hibernate中的多表对应关系(二)
  11. Cockroachdb 三、副本设置
  12. 记redis的一个测试
  13. C语言清屏函数和光标隐藏函数
  14. 前端程序员简历模板整理和下载
  15. Raspberry Pi网络监控
  16. Win11系统怎么获得管理员权限
  17. 学习日记| javaScript在网页绘制国际象棋盘
  18. msi笔记本u盘装linux,msi微星笔记本bios设置u盘启动教程
  19. Unity给小鳄鱼洗澡2D流体水实现
  20. 怎么查EI论文的检索号

热门文章

  1. python基本数据类型(一)-python3.0学习笔记
  2. for和select循环语句的应用实践
  3. iptables基础概念
  4. saiku 展示优化
  5. 正则表达式入门(c#)
  6. 有趣的java小项目------猜拳游戏
  7. 产品设计:一层分类与多层分类模式的感悟
  8. OSPF特殊区域之stub和totally stub配置(二)
  9. PostgreSql Lock锁
  10. shiro web环境初始化过程