quartz源码分析之深刻理解job,sheduler,calendar,trigger及listener之间的关系
org.quartz包
包org.quartz是Quartz的主包,包含了客戶端接口。
其中接口有:
Calendar接口:
定義了一個關聯(lián)Trigger可能(或者不可能)觸發(fā)的時間空間。它沒有定義觸發(fā)的真實時間,而是用在在普通的Schedule需要限制Trigger觸發(fā)的時候。大部分Calendar包含默認所有的時間,并且用戶去排除部分時間。
因而,可以把Calendar看做是排除了block時間的時間(例如:一個每5分鐘觸發(fā)一次的調(diào)度在周末(sunday)不執(zhí)行,使用SimpleTrigger和WeeklyCalendar去排除周末這一天)。
注意:Calendar實現(xiàn)了序列化和可克隆接口。
?
?
Trigger接口:
?
?
?
?
?
?
CalendarIntervalTrigger:是一個具體的Trigger,用來觸發(fā)基于定時重復的JobDetail。
Trigger將會每隔N個calendar在trigger中定義的時間單元觸發(fā)一次。這個trigger不適合使用SimpleTrigger完成(例如由于每一個月的時間不是固定的描述),也不適用于CronTrigger(例如每5個月)。
若你使用Month作為時間間隔單位,請務必在設置開始時間時注意那天是否接近月底。例,如:你選擇1月31作為啟動時間,trigger 將設置觸發(fā)間隔為月份,下次觸發(fā)時間為2.28,下下次為3月28,接下來的觸發(fā)時間定位每月的28號,而不管那個月是否有31天。如果你需要一個在每月最后一天觸發(fā)的trigger(不管每月有多少天),請使用CronTrigger.
?
CronTrigger:使用CronExpression表達式作為觸發(fā)條件的Trigger的公開接口。
DailyTimeIntervalTrigger:用來觸發(fā)一個基于每天定時間隔執(zhí)行的JobDetail。Trigger在跟定的時間內(nèi)每隔N(個體RepeatInterval())秒、分、小時(getRepeatIntervalUnit())觸發(fā)一次。
例一:每天8:00~11:00之間每72分鐘執(zhí)行一次,它的觸發(fā)事件為8:00,9:12,10:24,然后明天繼續(xù):8:00,9:12,10:24。
例二:從周一到周五的每天9:20~16:47 每隔23分鐘執(zhí)行一次。
每天,開始時間被重置為startTimeOfDay,直至一天endTimeOfDay到之前,都將重復的間隔時間向上加。
TriggerListener接口
?
?
Job接口:
Job:job代表了要允許的任務即業(yè)務邏輯。它必須具有一個公開的無參構(gòu)造方法。JobDataMap提供了Job實例參數(shù)數(shù)據(jù)的機制,它會在一些實現(xiàn)給接口的類中需要這一機制。有唯一的方法:execute(JobExecutionContext context):當一個關聯(lián)到這個job的Trigger需要觸發(fā)時由Scheduler來調(diào)用該方法。
?
JobDetail:保存一個job實例的詳細屬性。它在JobBuilder中創(chuàng)建/定義。
JobDetailImpl:存一個job實例的詳細屬性,Quartz不保存一個Job類的真實實例,相反,允許你通過使用JobDetail定義一個job實例。Job 有名稱和所屬的組別,scheduler可以通過組別和名稱來找到唯一的一個job。Trigger 是job被調(diào)度的機制,許多Trigger可以指向同一個Job,但一個Trigger僅僅能執(zhí)行一個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
實現(xiàn)了該接口的類會監(jiān)聽JobDetail執(zhí)行的方法。通常,使用Scheduler的應用將不會應用這一機制。
ListenerManager:JobListener提供了對Job執(zhí)行的監(jiān)聽;TriggerListener提供對trigger觸發(fā)的監(jiān)聽;SchedulerListener提供了Scheduler事件和錯誤的監(jiān)聽。通過ListenerManager接口將Listener和本地scheduler關聯(lián)到一起。ListenerManagerImpl是實現(xiàn)類。
?
Listener的注冊順序是保持的,因此Listener的監(jiān)聽順序和他們注冊的順序一致。
?
JobFactory接口:
public class PropertySettingJobFactory extends SimpleJobFactory {}
public class SimpleJobFactory implements JobFactory {}
?
TriggerFiredBundle:JobStore返回給QuartzSchedulerThread的執(zhí)行時期數(shù)據(jù)。
?? 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關聯(lián)的Trigger觸發(fā)時(當調(diào)度到達時間)執(zhí)行該job。
Scheduler實例有SchedulerFactory創(chuàng)建產(chǎn)生。一個已經(jīng)創(chuàng)建或者初始化的scheduler可以被創(chuàng)建它的工廠查詢和使用。在一個scheduler被創(chuàng)建后,它處于”STAND-BY”模式,在觸發(fā)任何job前需要使用它的start()方法來啟動。
客戶端程序通過定義一個實現(xiàn)了job接口的類來創(chuàng)建Job,JobDetail對象同時對創(chuàng)建(客戶端)來定義一個單獨的job實例。JobDetail實例然后通過ScheduleJob(JobDetail,Trigger)或者addJob(JobDetail,boolean)方法注冊到Scheduler。
Trigger定義用來觸發(fā)基于給定Scheduler的單獨的job實例,SimpleTrigger對觸發(fā)一次或精確時間的觸發(fā)、在給定延遲后重復觸發(fā)的應用中非常有用。Contrigger允許基于一天中的具體時間、一周中的一天、一月中的一天、一年中的一個月的調(diào)度。
Job和trigger都具有名稱和關聯(lián)的組別,這是它們在一個單獨Scheduler的唯一身份識別碼。組別的這個特征在創(chuàng)建邏輯組或?qū)ob和Trigger進行歸類時非常有用。如果你不想對給定的job和trigger指定一個分組,可以使用默認組常量,這個常量已經(jīng)在接口中定義好了。
?
存儲的Job也可以手動觸發(fā),通過使用trigger(String JobName,String jobGroup)這個方法可以實現(xiàn)手動觸發(fā)job。
?
客戶端程序可能會對Quartz中的Listener接口感興趣,JobListener提供了對job執(zhí)行的監(jiān)聽;TriggerListner提供了對Trigger觸發(fā)的監(jiān)聽;SchedulerListener提供了對事件調(diào)度和錯誤的監(jiān)聽。通過使用ListenerManager接口將Listener和本地的Scheduler關聯(lián)起來。Scheduler的創(chuàng)建和配置都可以自定義。請參考發(fā)布的Quartz的文檔。
?
?
SchedulerListener接口:
<略>
?
org.quartz.core包
JobRunShell
jobRunShell實例負責為job運行提供安全的環(huán)境、運行job所需工作、捕獲排除的任何異常、更新執(zhí)行完成job代碼的Trigger等。
jobRunShell實例由JobRunShellFactory創(chuàng)建,當sheduler決定觸發(fā)一個job時,QuartzSchedulerThread從配置的線程池中返回一個shell。看一下jobRunShel的調(diào)用關系:
/**
???? * <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啟動時調(diào)用JobRunShell
JobRunShell shell = null;
try{
?? shell = qsRsrcs.getJobRunShellFactory().createJobRunShell(bndle);
?? shell.initialize(qs);
?? }
?
?
?
?
?
QuartzScheduler
這個類是Quartz的核心,間接繼承了Scheduler接口,包含了調(diào)度Job、注冊JobListener實例的方法。
QuartzSchedulerResources:包含了JobStore、線程池等創(chuàng)建一個QuartzScheduler實例所必須要的所有資源。
?
?
SchedulerContext:保存job運行時需要的上下文/環(huán)境數(shù)據(jù),這個特征和J2EE中servlet的ServletContext特征特別相像。
以后的Quartz版本將會在代理實例和單獨的scheduler實例如何在SchedulerContext擴展數(shù)據(jù)做出區(qū)分。
?
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);
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/4237895.html
總結(jié)
以上是生活随笔為你收集整理的quartz源码分析之深刻理解job,sheduler,calendar,trigger及listener之间的关系的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kafka入门:简介、使用场景、设计原理
- 下一篇: Linux ps aux指令詳解--转