`

Quartz学习笔记(一)

    博客分类:
  • J2EE
阅读更多

Quartz特点

1) Quartz能嵌入到任何独立的应用中运行。 

2) Quartz能在应用服务器或者 Servlet 容器中实例化,并且能够参与 XA 事务。 

3) Quartz能够以独立的方式运行(在它自己的Java虚拟机中),可以通过 RMI使用

Quartz。 

4) Quartz可以被实例化为独立程序的集群(有负载均衡和容错能力)。 

Quartz功能介绍

任务执行(Job Execution

1) 任务是任何实现简单 Job 接口的 Java 类,这样开发者能够执行任何完成他们工作

的任务。

2) 任务类的实例可以由 Quartz实例化,也可以由你的程序框架实例化。

当触发器被触发时,日程管理器将会通知某个或者多个实现了JobListener 或 

TriggerListener的对象(监听器可以是简单的Java对象,或者 EJBs,或者 JMS 消息发布器,等等)。这些监听器在任务执行完毕后也会接到通知。

3) 任务被完成后,他们会返回一个“任务完成码(JobCompletionCode)”,这个

“任务完成码”告知日程管理器任务执行的结果是成功还是失败。日程管理器会根据成功或者失败码来采取措施,比如:立即重新执行任务

任务持久化(Job Persistence

1) Quartz设计中包括了一个JobStore接口,这样,实现这个接口的 Job多种机制实现Job 的存储。

2) 存储在数据库中:通过使用 JDBCJobStore,所有的 Jobs和 Triggers 被配置为“non-volatile(

轻快)的方式。即,通过 JDBC 存储在关系数据库中。

3) 存储在RAM中:通过使用 RAMJobStore,所有Jobs和 Triggers 被存储在 RAM。因此,在程序执行中没有被持久化,但这种方式的优点就是不需要外部数据库。

事务(Transactions

1) Quartz通过JobStoreCMTJDBCJobStore的一个子类)可参与 JTA 事务。

2) Quartz可以管理JTA (工作任务分析)事务(开始或者提交事务)。

集群(Clustering

1) Fail-over.(容错)

2) Load balancing.(负载均衡)

监听器及插件(Listeners & Plug-Ins

1) 应用可以通过实现一个或者多个监听器接口来实现捕捉日程事件,以监视或控制任务/触发器的行为。

2) 可以通过插件的机制来扩展 Quartz 的功能。例如:记录任务执行历史的日志,或者从文件中载入任务和触发器的定义。

3) Quartz自带了一些“factory built(内建)”的插件和监听器。

什么是Quartz

Quartz是一个任务日程管理系统,这个系统可以与任何其他软件系统集成或者一起

用。“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。

Quartz相当“轻量”,并且需要非常少的步骤/配置,如果需求比较基本,Quartz确实非常容易使用。

Quartz具有容错性,并且可以在你系统重起的时候持久化(记住)被纳入日程的任务。

Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有 Quartz核心功能。这些功能的主要接口(API)Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。

如果你想将软件组件的执行纳入到日程中,它们只需简单地实现 Job 接口,这个接口有一个 execute()方法。如果希望在日程安排的时间到达时通知组件,那么这些组件应实现 TriggerListener或者 JobListener接口。

Quartz主过程可以在应用中启动或者运行,也可以作为一个独立的应用(带有RMI<远程服务接口>接口),或者在一个J2EE 应用服务器中运行,并且可作为其它 J2EE组件的一种引用资源。

Quartzjava.util.TimerJDK1.3起)的区别

1Java 定时器没有持久化机制。  

2Java 定时器的日程管理不够灵活(只能设置开始时间、重复的间隔,设置特定的日期、时间等)  

3Java 定时器没有使用线程池(每个Java 定时器使用一个线程)  

4Java 定时器没有切实的管理方案,你不得不自己完成存储、组织、恢复任务的措施。

夏令时和触发器

SimpleTrigger 总是每隔若干毫秒触发,而同夏令时没有关系。

CronTrigger 总是在给定的时间触发,然后计算它下次触发的时间。

开始使用Quartz

Job:接口:只有一个方法:oid execute(JobExecutionContext context)

JobDetailQuartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描 述、关联监听器等信息,JobDetail承担了这一角色。

通过该类的构造函数可以更具体地了解它的功用:JobDetail(java.lang.String name, java.lang.String group, java.lang.Class jobClass),该构造函数要求指定Job的实现类,以及任务在Scheduler中的组名和Job名称;

Trigger是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当仅需触 发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规 则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等

Calendarorg.quartz.Calendarjava.util.Calendar不同,它是一些日历特定时间点的集合(可以简 单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时 间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。一个Trigger可以和多个Calendar关联,以便排除或 包含某些时间点。

Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在 Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯 一,JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler定义了多个接口方法, 允许外部通过组及名称访问和控制容器中Trigger和JobDetail。

Scheduler可以将Trigger绑定到某一JobDetail中,这样当Trigger触发时,对应的Job就被执行。一个Job可以对应 多个Trigger,但一个Trigger只能对应一个Job。可以通过SchedulerFactory创建一个Scheduler实例。 Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和 Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下 文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。可以通过Scheduler# getContext()获取对应的SchedulerContext实例

ThreadPoolScheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。

Job有一个StatefulJob子接口,代表有状态的任务,该接口是一个没有方法的标签接口,其目的是让Quartz知道任务的类型,以便采用 不同的执行方案。无状态任务在执行时拥有自己的JobDataMap拷贝,对JobDataMap的更改不会影响下次的执行。而有状态任务共享共享同一个 JobDataMap实例,每次任务执行对JobDataMap所做的更改会保存下来,后面的执行可以看到这个更改,也即每次执行任务后都会对后面的执行 发生影响。

如果Quartz使用了数据库持久化任务调度信息,无状态的JobDataMap仅会在Scheduler注册任务时保持一次,而有状态任务对应的JobDataMap在每次执行任务后都会进行保存。

Trigger自身也可以拥有一个JobDataMap,其关联的Job可以通过 JobExecutionContext#getTrigger().getJobDataMap()获取Trigger中的JobDataMap。不管 是有状态还是无状态的任务,在任务执行期间对TriggerJobDataMap所做的更改都不会进行持久,也即不会对下次的执行产生影响。

监听体系Quartz拥有完善的事件和监听体系,大部分组件都拥有事件,如任务执行前事件、任务执行后事件、触发器触发前事件、触发后事件、调度器开始事件、关闭事件等等,可以注册相应的监听器处理感兴趣的事件。

SimpleTrigger

SimpleTrigger拥有多个重载的构造函数,用以在不同场合下构造出对应的实例:

1) SimpleTrigger(String name, String group):通过该构造函数指定Trigger所属组和名称;

2 SimpleTrigger(String name, String group, Date startTime):除指定Trigger所属组和名称外,还可以指定触发的开发时间

3 SimpleTrigger(String name, String group, Date startTime, Date endTime, int repeatCount, long repeatInterval):除指定以上信息外,还可以指定结束时间、重复执行次数、时间间隔等参数;

4 SimpleTrigger(String name, String group, String jobName, String jobGroup, Date startTime, Date endTime, int repeatCount, long repeatInterval):这是最复杂的一个构造函数,在指定触发参数的同时,还通过jobGroupjobName,让该Trigger和 Scheduler中的某个任务关联起来。

CronTrigger

Quartz使用类似于Linux下的Cron表达式定义时间规则,Cron表达式由6或7个由空格分隔的时间字段组成,如表1所示:

分别代表秒、分钟、小时、日期、月份、星期、年

位置

时间域名

允许值

允许的特殊字符

1

0-59

, - * /

2

分钟

0-59

, - * /

3

小时

0-23

, - * /

4

日期

1-31

, - * ? / L W C 

5

月份

1-12

, - * /

6

星期

1-7

, - * ? / L C #

7

年(可选)

空值1970-2099

, - * /

Cron表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功能,细说如下:

1) 星号(*):可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”;

2) 问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符

3) 减号(-)表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12;

4) 逗号(,)表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五;

5) 斜杠(/):x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;

6) L:该字符只在日期和星期字段中使用代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的 31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后 X天”,例如,6L表示该月的最后一个星期五;

7) W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星 期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围;

8) LW组合在日期字段可以组合使用LW,它的意思是当月的最后一个工作日

9) 井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;

  10)  C:该字符只在日期和星期字段中使用代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于Quartz使用类似于Linux下的Cron表达式定义时间规则,Cron表达式由6或7个由空格分隔的时间字段组成

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics