org.quartz包

包org.quartz是Quartz的主包,包含了客户端接口。

其中接口有:

Calendar接口:

定义了一个关联Trigger可能(或者不可能)触发的时间空间。它没有定义触发的真实时间,而是用在在普通的Schedule需要限制Trigger触发的时候。大部分Calendar包含默认所有的时间,并且用户去排除部分时间。

因而,可以把Calendar看做是排除了block时间的时间(例如:一个每5分钟触发一次的调度在周末(sunday)不执行,使用SimpleTrigger和WeeklyCalendar去排除周末这一天)。

注意:Calendar实现了序列化和可克隆接口。

Trigger接口:

CalendarIntervalTrigger是一个具体的Trigger,用来触发基于定时重复的JobDetail。

Trigger将会每隔N个calendar在trigger中定义的时间单元触发一次。这个trigger不适合使用SimpleTrigger完成(例如由于每一个月的时间不是固定的描述),也不适用于CronTrigger(例如每5个月)。

若你使用Month作为时间间隔单位,请务必在设置开始时间时注意那天是否接近月底。例,如:你选择1月31作为启动时间,trigger 将设置触发间隔为月份,下次触发时间为2.28,下下次为3月28,接下来的触发时间定位每月的28号,而不管那个月是否有31天。如果你需要一个在每月最后一天触发的trigger(不管每月有多少天),请使用CronTrigger.

CronTrigger:使用CronExpression表达式作为触发条件的Trigger的公开接口。

DailyTimeIntervalTrigger用来触发一个基于每天定时间隔执行的JobDetail。Trigger在跟定的时间内每隔N(个体RepeatInterval())秒、分、小时(getRepeatIntervalUnit())触发一次。

例一:每天8:00~11:00之间每72分钟执行一次,它的触发事件为8:00,9:12,10:24,然后明天继续:8:00,9:12,10:24。

例二:从周一到周五的每天9:20~16:47 每隔23分钟执行一次。

每天,开始时间被重置为startTimeOfDay,直至一天endTimeOfDay到之前,都将重复的间隔时间向上加。

TriggerListener接口

Job接口:

Job:job代表了要允许的任务即业务逻辑。它必须具有一个公开的无参构造方法。JobDataMap提供了Job实例参数数据的机制,它会在一些实现给接口的类中需要这一机制。有唯一的方法:execute(JobExecutionContext context):当一个关联到这个job的Trigger需要触发时由Scheduler来调用该方法。

JobDetail:保存一个job实例的详细属性。它在JobBuilder中创建/定义。

JobDetailImpl:存一个job实例的详细属性,Quartz不保存一个Job类的真实实例,相反,允许你通过使用JobDetail定义一个job实例。Job 有名称和所属的组别,scheduler可以通过组别和名称来找到唯一的一个job。Trigger 是job被调度的机制,许多Trigger可以指向同一个Job,但一个Trigger仅仅能执行一个Job

private String name;

private String group = Scheduler.DEFAULT_GROUP;

private String description;

private Class<? extends Job> jobClass;

private JobDataMap jobDataMap;

private boolean durability = false;

private boolean shouldRecover = false;

private transient JobKey key = null;

其中,JobKey定义了job的名称和组别。

JobBuilder:用来初始化JobDetail实例。

JobListener

实现了该接口的类会监听JobDetail执行的方法。通常,使用Scheduler的应用将不会应用这一机制。

ListenerManager:JobListener提供了对Job执行的监听;TriggerListener提供对trigger触发的监听;SchedulerListener提供了Scheduler事件和错误的监听。通过ListenerManager接口将Listener和本地scheduler关联到一起。ListenerManagerImpl是实现类。

 

Listener的注册顺序是保持的,因此Listener的监听顺序和他们注册的顺序一致。

JobFactory接口:

public class PropertySettingJobFactory extends SimpleJobFactory {}

public class SimpleJobFactory implements JobFactory {}

TriggerFiredBundle:JobStore返回给QuartzSchedulerThread的执行时期数据。

private JobDetail job;

private OperableTrigger trigger;

private Calendar cal;

private boolean jobIsRecovering;

private Date fireTime;

private Date scheduledFireTime;

private Date prevFireTime;

private Date nextFireTime;

Scheduler接口:

一个scheduler维护一个JobDetail和一个或者多个Trigger的注册。一旦注册,scheduler负责在job关联的Trigger触发时(当调度到达时间)执行该job。

Scheduler实例有SchedulerFactory创建产生。一个已经创建或者初始化的scheduler可以被创建它的工厂查询和使用。在一个scheduler被创建后,它处于”STAND-BY”模式,在触发任何job前需要使用它的start()方法来启动。

客户端程序通过定义一个实现了job接口的类来创建Job,JobDetail对象同时对创建(客户端)来定义一个单独的job实例。JobDetail实例然后通过ScheduleJob(JobDetail,Trigger)或者addJob(JobDetail,boolean)方法注册到Scheduler。

Trigger定义用来触发基于给定Scheduler的单独的job实例,SimpleTrigger对触发一次或精确时间的触发、在给定延迟后重复触发的应用中非常有用。Contrigger允许基于一天中的具体时间、一周中的一天、一月中的一天、一年中的一个月的调度。

Job和trigger都具有名称和关联的组别,这是它们在一个单独Scheduler的唯一身份识别码。组别的这个特征在创建逻辑组或对job和Trigger进行归类时非常有用。如果你不想对给定的job和trigger指定一个分组,可以使用默认组常量,这个常量已经在接口中定义好了。

存储的Job也可以手动触发,通过使用trigger(String JobName,String jobGroup)这个方法可以实现手动触发job。

客户端程序可能会对Quartz中的Listener接口感兴趣,JobListener提供了对job执行的监听;TriggerListner提供了对Trigger触发的监听;SchedulerListener提供了对事件调度和错误的监听。通过使用ListenerManager接口将Listener和本地的Scheduler关联起来。Scheduler的创建和配置都可以自定义。请参考发布的Quartz的文档。

SchedulerListener接口:

<略>

org.quartz.core包

JobRunShell

jobRunShell实例负责为job运行提供安全的环境、运行job所需工作、捕获排除的任何异常、更新执行完成job代码的Trigger等。

jobRunShell实例由JobRunShellFactory创建,当sheduler决定触发一个job时,QuartzSchedulerThread从配置的线程池中返回一个shell。看一下jobRunShel的调用关系:

  1. QuartzScheduler构造方法初始化线程池:

/**

* <p>

* Create a <code>QuartzScheduler</code> with the given configuration

* properties.

* </p>

*

* @see QuartzSchedulerResources

*/

public QuartzScheduler(QuartzSchedulerResources resources, long idleWaitTime, @Deprecated long dbRetryInterval)

throws SchedulerException {

this.resources = resources;

if (resources.getJobStore() instanceof JobListener) {

addInternalJobListener((JobListener)resources.getJobStore());

}

this.schedThread = new QuartzSchedulerThread(this, resources);

ThreadExecutor schedThreadExecutor = resources.getThreadExecutor();

schedThreadExecutor.execute(this.schedThread);

if (idleWaitTime > 0) {

this.schedThread.setIdleWaitTime(idleWaitTime);

}

jobMgr = new ExecutingJobsManager();

addInternalJobListener(jobMgr);

errLogger = new ErrorLogger();

addInternalSchedulerListener(errLogger);

signaler = new SchedulerSignalerImpl(this, this.schedThread);

if(shouldRunUpdateCheck())

updateTimer = scheduleUpdateCheck();

else

updateTimer = null;

getLog().info("Quartz Scheduler v." + getVersion() + " created.");

}

QuartzSchedulerThread启动时调用JobRunShell

JobRunShell shell = null;

try{

shell = qsRsrcs.getJobRunShellFactory().createJobRunShell(bndle);

shell.initialize(qs);

}

QuartzScheduler

这个类是Quartz的核心,间接继承了Scheduler接口,包含了调度Job、注册JobListener实例的方法。

QuartzSchedulerResources:包含了JobStore、线程池等创建一个QuartzScheduler实例所必须要的所有资源。

SchedulerContext:保存job运行时需要的上下文/环境数据,这个特征和J2EE中servlet的ServletContext特征特别相像。

以后的Quartz版本将会在代理实例和单独的scheduler实例如何在SchedulerContext扩展数据做出区分。

SchedulerSignaler:JobStore实例使用的接口,用来传回信号到QuartzScheduler。

void notifyTriggerListenersMisfired(Trigger trigger);

void notifySchedulerListenersFinalized(Trigger trigger);

void notifySchedulerListenersJobDeleted(JobKey jobKey);

void signalSchedulingChange(long candidateNewNextFireTime);

void notifySchedulerListenersError(String string, SchedulerException jpe);

quartz源码分析之深刻理解job,sheduler,calendar,trigger及listener之间的关系的更多相关文章

  1. quartz源码分析——执行引擎和线程模型

    title: quartz源码分析--执行引擎和线程模型 date: 2017-09-09 23:14:48 categories: quartz tags: [quartz, 源码分析] --- - ...

  2. Quartz源码分析

    先简单介绍一下quartz,Quartz是一个功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中 - 从最小的独立应用程序到最大的电子商务系统.quartz可用于创建执行数十,数百甚至数十 ...

  3. 学习JUC源码(3)——Condition等待队列(源码分析结合图文理解)

    前言 在Java多线程中的wait/notify通信模式结尾就已经介绍过,Java线程之间有两种种等待/通知模式,在那篇博文中是利用Object监视器的方法(wait(),notify().notif ...

  4. Java ArrayList源码分析(有助于理解数据结构)

    arraylist源码分析 1.数组介绍 数组是数据结构中很基本的结构,很多编程语言都内置数组,类似于数据结构中的线性表 在java中当创建数组时会在内存中划分出一块连续的内存,然后当有数据进入的时候 ...

  5. 学习JUC源码(1)——AQS同步队列(源码分析结合图文理解)

    前言 最近结合书籍<Java并发编程艺术>一直在看AQS的源码,发现AQS核心就是:利用内置的FIFO双向队列结构来实现线程排队获取int变量的同步状态,以此奠定了很多并发包中大部分实现基 ...

  6. angular源码阅读,依赖注入的原理:injector,provider,module之间的关系。

    最开始使用angular的时候,总是觉得它的依赖注入方式非常神奇. 如果你跳槽的时候对新公司说,我曾经使用过angular,那他们肯定会问你angular的依赖注入原理是什么? 这篇博客其实是angu ...

  7. 源码分析:动态分析 Linux 内核函数调用关系

    源码分析:动态分析 Linux 内核函数调用关系 时间 2015-04-22 23:56:07  泰晓科技 原文  http://www.tinylab.org/source-code-analysi ...

  8. quartz2.x源码分析——启动过程

    title: quartz2.x源码分析--启动过程 date: 2017-04-13 14:59:01 categories: quartz tags: [quartz, 源码分析] --- 先简单 ...

  9. Kafka源码分析(三) - Server端 - 消息存储

    系列文章目录 https://zhuanlan.zhihu.com/p/367683572 目录 系列文章目录 一. 业务模型 1.1 概念梳理 1.2 文件分析 1.2.1 数据目录 1.2.2 . ...

随机推荐

  1. Emmet(前身是zen coding)介绍和使用

    Zen coding - 一种快速编写HTML/CSS代码的方法.它使用仿CSS选择器的语法来快速开发HTML和CSS - 由Sergey Chikuyonok开发. 现在它改名为了Emmet,并且搭 ...

  2. HTML本地测试成功后上传博客注意事项

    需要注意不要跟博客已经存在的样式(CSS)或功能(JavaScript)起冲突 功能名一定不要一样 样式名尽量不一样 如果样式名一样,存在属性名的对应属性值尽量跟博客内相同

  3. 做最好的自己(Be Your Personal Best)

    成功——做最好的自己 价值观——成功源于诚信 积极主动——成功的选择在于自己 同理心——人际交往的基础 自信——用信心放飞自我 自省——在反思中走向成功 勇气——勇往直前的精神 胸怀——海纳百川的境界 ...

  4. BZOJ_1625_ [Usaco2007_Dec]_宝石手镯_(01背包)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1625 01背包裸题. p.s.随便点开一道就是水题... 分析 ... #include &l ...

  5. ☀【Zepto】

    http://zeptojs.com/ https://github.com/madrobby/zepto Zepto 中文手册 http://www.360weboy.com/handbook/ze ...

  6. -_-#【减少 DOM 元素】textarea, script 延迟渲染

    淘宝详情页的 BigRender 优化与存放大块 HTML 内容的最佳方式 淘宝详情页的BigRender优化的最佳方式 <!DOCTYPE html> <html> < ...

  7. [039] 微信公众帐号开发教程第15篇-自定义菜单的view类型(访问网页)

    引言及内容概要 距离写上一篇文章<自定义菜单的创建及菜单事件响应>整整过了两个月的时间,那时公众平台还没有开放view类型的菜单.在不久前,微信公众平台悄悄开放了view类型的菜单,却没有 ...

  8. 布隆过滤器(Bloom Filter)的原理和实现

    什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...

  9. Flex 箭头(军标)库封装完成

    封装的一个月,在这个月期间还完成的一些其它的工作:公司有规定不能公布代码,我可以讲一下大致的流程,真的很抱歉! 1.用B样条曲线画箭头的两侧的曲线,这个要注意了,不要贝塞尔曲线,因为贝塞尔曲线的算法会 ...

  10. 招商银行支付dll在64位windows系统下的注册使用问题

    按照文档中的说明,注册完dll后,依然报找不到COM组件的错误.尝试过以下方法: 1.在VS中将项目编译目标改为x86,只能解决VS可以启动程序的问题,一部署到IIS中就出错. 2.估计是因为权限问题 ...