1. 程式人生 > >Quartz教程:快速入門

Quartz教程:快速入門

原文連結 | 譯文連結 | 翻譯:nkcoder | 校對:方騰飛

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

歡迎來到quartz快速入門教程。閱讀本教程,你將會了解:

  • quartz下載
  • quartz安裝
  • 根據你的需要,配置Quartz
  • 開始一個示例應用

當熟悉了quratz排程的基本功能後,可以嘗試一些更高階的特性,比如Where,這個一個企業級功能,可以讓job和trigger執行在指定的,而不是隨機的Terracotta客戶端上。

下載和安裝

首先,下載最新的穩定版 – 不用註冊。解壓並安裝。

Quartz jar檔案

quartz安裝包根目錄的lib/目錄下有很多的jar包。其中,quartz-xxx.jar(其中xxx是版本號)是最主要的。為了使用quartz,必須將該jar包放在應用的classpath下;

下載後,解壓,然後將quartz-xxx.jar放到你的應用中。

我主要是在應用伺服器的環境中使用quartz,所以一般將quartz jar包放到應用中(.ear或.war)。當然,如果你希望在很多應用中使用quartz,將quartz的jar包放在應用伺服器(appserver)的classpath下即可。如果你只是希望在獨立的應用中使用quartz,將quartz的jar包和你的應用依賴的其它jar包放在一起即可。

quzrtz依賴一些第三方的庫(以jar包的形式),這些庫位於quartz安裝包的lib目錄下。要使用quartz的所有功能,必須將所有的第三方jar包都放到classpath下。如果你開發的是一個獨立的quartz應用,建議將所有的jar包都放到classpath下;如果是在應用伺服器環境下使用quartz,其中有些包可能已經存在於classpath中了,因此你需要自己選擇。

在應用伺服器環境下,如果同一個jar檔案,存在兩個不同的版本,要注意,可能會產生一些奇怪的結果;比如,WebLogic包含了一個J2EE的實現(在weblogic.jar中),該實現與servlet.jar的實現可能不一致。此時,應該從你的應用中排除掉servlet.jar,這樣你就知道使用的是哪個類了。

properties檔案

quartz使用名為quartz.properties的配置檔案。剛開始時該配置檔案不是必須的,但是為了使用最基本的配置,該檔案必須位於classpath下。

基於我的個人情況舉個例子,我的應用是基於WebLogic Workshop開發的。我將所有的配置檔案(包括quartz.properties)放到應用根目錄下的一個專案中。當我將專案打包成.ear檔案時,放置配置檔案的專案會以jar包的形式進入最終的.ear包,所以quartz.properties檔案就自動位於classpath中了。

如果你準備構建一個使用quartz的web應用(以.war包的形式),你應該將quartz.properties檔案放到WEB-INF/classes目錄下。

配置

這裡包含很多內容。quartz是一個配置很靈活的應用。配置quartz最好的方式是,編輯quartz.properties檔案,然後放到應用的classpath下。

quartz的安裝包中包含了一些配置檔案的示例,位於example/目錄下。我建議你建立自己的quartz.properties檔案,而不是簡單地從示例中拷貝並刪除不需要的部分。這樣看起來更整潔,而且你也會了解到quartz的更多功能。

關於quartz配置檔案的詳細文件,請查閱Quartz配置參考

為了使用quartz,一個基本的quartz.properties配置檔案如下所示:

org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

上述配置的scheduler有如下特點:

  • org.quartz.scheduler.instanceName scheduler的名稱為“MyScheduler”
  • org.quartz.threadPool.threadCount 執行緒池中有3個執行緒,即最多可以同時執行3個job;
  • org.quartz.jobStore.class quartz的所有資料,包括job和trigger的配置,都會儲存在記憶體中(而不是資料庫裡)。如果你想使用quartz的資料庫儲存功能(校對注:設定成另外一個類),我們建議在使用資料庫儲存之前,先使用記憶體儲存(RamJobStore)。

示例應用

下載和安裝完quartz後,是時候開發一個示例應用,並讓它跑起來了。下面的示例程式碼,獲取scheduler例項物件,啟動,然後關閉。

QuartzTest.java


    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.impl.StdSchedulerFactory;
    import static org.quartz.JobBuilder.*;
    import static org.quartz.TriggerBuilder.*;
    import static org.quartz.SimpleScheduleBuilder.*;

    public class QuartzTest {

        public static void main(String[] args) {

            try {
                // Grab the Scheduler instance from the Factory 
                Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

                // and start it off
                scheduler.start();

                scheduler.shutdown();

            } catch (SchedulerException se) {
                se.printStackTrace();
            }
        }
    }

當你呼叫StdSchedulerFactory.getDefaultScheduler()獲取scheduler例項物件後,在呼叫scheduler.shutdown()之前,scheduler不會終止,因為還有活躍的執行緒在執行。

注意示例程式碼中的靜態匯入(static import),下面的程式碼中也會用到它們。

如果你沒有配置日誌輸出,所有的日誌會輸出到控制檯,比如:

[INFO] 21 Jan 08:46:27.857 AM main [org.quartz.core.QuartzScheduler]
Quartz Scheduler v.2.0.0-SNAPSHOT created.

[INFO] 21 Jan 08:46:27.859 AM main [org.quartz.simpl.RAMJobStore]
RAMJobStore initialized.

[INFO] 21 Jan 08:46:27.865 AM main [org.quartz.core.QuartzScheduler]
Scheduler meta-data: Quartz Scheduler (v2.0.0) 'Scheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 50 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.


[INFO] 21 Jan 08:46:27.865 AM main [org.quartz.impl.StdSchedulerFactory]
Quartz scheduler 'Scheduler' initialized from default resource file in Quartz package: 'quartz.properties'

[INFO] 21 Jan 08:46:27.866 AM main [org.quartz.impl.StdSchedulerFactory]
Quartz scheduler version: 2.0.0

[INFO] 21 Jan 08:46:27.866 AM main [org.quartz.core.QuartzScheduler]
Scheduler Scheduler_$_NON_CLUSTERED started.

[INFO] 21 Jan 08:46:27.866 AM main [org.quartz.core.QuartzScheduler]
Scheduler Scheduler_$_NON_CLUSTERED shutting down.

[INFO] 21 Jan 08:46:27.866 AM main [org.quartz.core.QuartzScheduler]
Scheduler Scheduler_$_NON_CLUSTERED paused.

[INFO] 21 Jan 08:46:27.867 AM main [org.quartz.core.QuartzScheduler]
Scheduler Scheduler_$_NON_CLUSTERED shutdown complete.

你可以在start()和shutdown()之間做一些有趣的事情:

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

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

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

在呼叫shutdown()之前,你需要給job的觸發和執行預留一些時間,比如,你可以呼叫Thread.sleep(60000)讓執行緒睡眠一段時間。

好了,自己去探索吧!