閱讀771 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Quartz教程二:API,Job和Trigger

本係列教程由quartz-2.2.x官方文檔翻譯、整理而來,希望給同樣對quartz感興趣的朋友一些參考和幫助,有任何不當或錯誤之處,歡迎指正;有興趣研究源碼的同學,可以參考我對quartz-core源碼的注釋(進行中)。

Quartz API

Quartz API核心接口有:

  • Scheduler – 與scheduler交互的主要API;
  • Job – 你通過scheduler執行任務,你的任務類需要實現的接口;
  • JobDetail – 定義Job的實例;
  • Trigger – 觸發Job的執行;
  • JobBuilder – 定義和創建JobDetail實例的接口;
  • TriggerBuilder – 定義和創建Trigger實例的接口;

Scheduler的生命期,從SchedulerFactory創建它時開始,到Scheduler調用shutdown()方法時結束;Scheduler被創建後,可以增加、刪除和列舉Job和Trigger,以及執行其它與調度相關的操作(如暫停Trigger)。但是,Scheduler隻有在調用start()方法後,才會真正地觸發trigger(即執行job),見教程一

Quartz提供的“builder”類,可以認為是一種領域特定語言(DSL,Domain Specific Language)。教程一中有相關示例,這裏是其中的代碼片段:(校對注:這種級聯的API非常方便用戶使用,大家以後寫對外接口時也可以使用這種方式)

    // define the job and tie it to our HelloJob class
    JobDetail job = newJob(HelloJob.class)
      .withIdentity("myJob", "group1") // name "myJob", group "group1"
      .build();

    // Trigger the job to run now, and then every 40 seconds
    Trigger trigger = newTrigger()
      .withIdentity("myTrigger", "group1")
      .startNow()
      .withSchedule(simpleSchedule()
          .withIntervalInSeconds(40)
          .repeatForever())            
      .build();

    // Tell quartz to schedule the job using our trigger
    sched.scheduleJob(job, trigger);

定義job的代碼使用的是從JobBuilder靜態導入的方法。同樣,定義trigger的代碼使用的是從TriggerBuilder靜態導入的方法 。 另外,也導入了SimpleSchedulerBuilder類的靜態方法;

從DSL裏靜態導入的語句如下:

    import static org.quartz.JobBuilder.*;
    import static org.quartz.SimpleScheduleBuilder.*;
    import static org.quartz.CronScheduleBuilder.*;
    import static org.quartz.CalendarIntervalScheduleBuilder.*;
    import static org.quartz.TriggerBuilder.*;
    import static org.quartz.DateBuilder.*;

SchedulerBuilder接口的各種實現類,可以定義不同類型的調度計劃(schedule);

DateBuilder類包含很多方法,可以很方便地構造表示不同時間點的java.util.Date實例(如定義下一個小時為偶數的時間點,如果當前時間為9:43:27,則定義的時間為10:00:00)。

Job和Trigger

一個job就是一個實現了Job接口的類,該接口隻有一個方法:

Job接口:

    package org.quartz;

    public interface Job {

    public void execute(JobExecutionContext context)
      throws JobExecutionException;
    }

當job的一個trigger被觸發後(稍後會講到),execute()方法會被scheduler的一個工作線程調用;傳遞給execute()方法的JobExecutionContext對象中保存著該job運行時的一些信息 ,執行job的scheduler的引用,觸發job的trigger的引用,JobDetail對象引用,以及一些其它信息。

JobDetail對象是在將job加入scheduler時,由客戶端程序(你的程序)創建的。它包含job的各種屬性設置,以及用於存儲job實例狀態信息的JobDataMap。本節是對job實例的簡單介紹,更多的細節將在下一節講到。

Trigger用於觸發Job的執行。當你準備調度一個job時,你創建一個Trigger的實例,然後設置調度相關的屬性。Trigger也有一個相關聯的JobDataMap,用於給Job傳遞一些觸發相關的參數。Quartz自帶了各種不同類型的Trigger,最常用的主要是SimpleTrigger和CronTrigger。

SimpleTrigger主要用於一次性執行的Job(隻在某個特定的時間點執行一次),或者Job在特定的時間點執行,重複執行N次,每次執行間隔T個時間單位。CronTrigger在基於日曆的調度上非常有用,如“每個星期五的正午”,或者“每月的第十天的上午10:15”等。

為什麼既有Job,又有Trigger呢?很多任務調度器並不區分Job和Trigger。有些調度器隻是簡單地通過一個執行時間和一些job標識符來定義一個Job;其它的一些調度器將Quartz的Job和Trigger對象合二為一。在開發Quartz的時候,我們認為將調度和要調度的任務分離是合理的。在我們看來,這可以帶來很多好處。

例如,Job被創建後,可以保存在Scheduler中,與Trigger是獨立的,同一個Job可以有多個Trigger;這種鬆耦合的另一個好處是,當與Scheduler中的Job關聯的trigger都過期時,可以配置Job稍後被重新調度,而不用重新定義Job;還有,可以修改或者替換Trigger,而不用重新定義與之關聯的Job。

Key

將Job和Trigger注冊到Scheduler時,可以為它們設置key,配置其身份屬性。Job和Trigger的key(JobKey和TriggerKey)可以用於將Job和Trigger放到不同的分組(group)裏,然後基於分組進行操作。同一個分組下的Job或Trigger的名稱必須唯一,即一個Job或Trigger的key由名稱(name)和分組(group)組成。

對於Job和Trigger,你現在有一個大概的了解了,更詳細的介紹參見教程三教程四

最後更新:2017-05-23 17:32:06

  上一篇:go  Java8:Lambdas(二)學習怎樣去使用lambda表達式
  下一篇:go  Tomcat對keep-alive的實現邏輯