zoukankan      html  css  js  c++  java
  • quartz源码分析之深刻理解job,sheduler,calendar,trigger及listener之间的关系

    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);

     

     

  • 相关阅读:
    文件的权限
    正则表达式
    软硬链接的学习
    linux系统中的文件类型和扩展名
    把数组排成最小的数
    整数中1出现的次数(从1到n整数中1出现的次数)
    最小的K个数
    连续子数组的最大和
    数组中出现次数超过一半的数字
    字符串的排列
  • 原文地址:https://www.cnblogs.com/davidwang456/p/4237895.html
Copyright © 2011-2022 走看看