你曾經(jīng)需要應(yīng)用執(zhí)行一個(gè)任務(wù)嗎?這個(gè)任務(wù)每天或每周星期二晚上11:30,或許僅僅每個(gè)月的最后一天執(zhí)行。一個(gè)自動(dòng)執(zhí)行而無須干預(yù)的任務(wù)在執(zhí)行過程中如果發(fā)生一個(gè)嚴(yán)重錯(cuò)誤,應(yīng)用能夠知到其執(zhí)行失敗并嘗試重新執(zhí)行嗎?你和你的團(tuán)隊(duì)是用java編程嗎?如果這些問題中任何一個(gè)你回答是,那么你應(yīng)該使用Quartz調(diào)度器。      旁注:Matrix目前就大量使用到了Quartz。比如,排名統(tǒng)計(jì)功能的實(shí)現(xiàn),在Jmatrix里通過Quartz定義了一個(gè)定時(shí)調(diào)度作業(yè),在每天凌晨一點(diǎn),作業(yè)開始工作,重新統(tǒng)計(jì)大家的Karma和排名等。      還有,RSS文件的生成,也是通過Quartz定義作業(yè),每隔半個(gè)小時(shí)生成一次RSS XML文件。      所以Quartz使用的地方很多,本文無疑是一篇很好的入門和進(jìn)階的文章,在此,感謝David w Johnson的努力!      Quartz讓作業(yè)調(diào)度簡單      Quartz是一個(gè)完全由java編寫的開源作業(yè)調(diào)度框架。不要讓作業(yè)調(diào)度這個(gè)術(shù)語嚇著你。盡管Quartz框架整合了許多額外功能, 但就其簡易形式看,你會(huì)發(fā)現(xiàn)它易用得簡直讓人受不了!。簡單地創(chuàng)建一個(gè)實(shí)現(xiàn)org.quartz.Job接口的java類。Job接口包含唯一的方法:      public void execute(JobExecutionContext context)   throws JobExecutionException;      在你的Job接口實(shí)現(xiàn)類里面,添加一些邏輯到execute()方法。一旦你配置好Job實(shí)現(xiàn)類并設(shè)定好調(diào)度時(shí)間表,Quartz將密切注意剩余時(shí)間。當(dāng)調(diào)度程序確定該是通知你的作業(yè)的時(shí)候,Quartz框架將調(diào)用你Job實(shí)現(xiàn)類(作業(yè)類)上的execute()方法并允許做它該做的事情。無需報(bào)告任何東西給調(diào)度器或調(diào)用任何特定的東西。僅僅執(zhí)行任務(wù)和結(jié)束任務(wù)即可。如果配置你的作業(yè)在隨后再次被調(diào)用,Quartz框架將在恰當(dāng)?shù)臅r(shí)間再次調(diào)用它。      如果你使用了其它流行的開源框架象struts,你會(huì)對(duì)Quartz的設(shè)計(jì)和部件感到舒適。雖然兩個(gè)開源工程是解決完全不同的問題,還是有很多相似的之處,就是開源軟件用戶每天感覺很舒適。Quartz能用在單機(jī)J2SE應(yīng)用中,作為一個(gè)RMI服務(wù)器,也可以用在web應(yīng)用中,甚至也可以用在J2EE應(yīng)用服務(wù)器中。      Quartz的發(fā)展史      盡管Quartz今年開始受到人們注意,但還是暫時(shí)流行。Quartz由James House創(chuàng)建并最初于2001年春天被加入sourceforge工程。接下來的幾年里,有許多新特征和版本出現(xiàn),但是直到項(xiàng)目遷移到新的站點(diǎn)并成為OpenSymphony項(xiàng)目家族的一員,才開始真正啟動(dòng)并受到應(yīng)有的關(guān)注。      James House仍然和幾個(gè)協(xié)助他的業(yè)余開發(fā)者參與大量開發(fā)工作。Quartz開發(fā)團(tuán)隊(duì)今年能發(fā)布幾個(gè)新版本,包括當(dāng)前正處在候選發(fā)布階段的1.5版。      上手Quartz      Quartz工程駐留在OpenSymphony站點(diǎn)上。在Quartz站點(diǎn)上可以找到許多有用的資源:JavaDocs,包含指南的文檔,CVS訪問,用戶和開發(fā)者論壇的連接,當(dāng)然也有下載。      從下載連接取得Quartz的發(fā)布版本,并且解壓到到本地目錄。這個(gè)下載文件包含了一個(gè)預(yù)先構(gòu)建好的Quartz二進(jìn)制文件(quartz.jar),你可以將它放進(jìn)自己的應(yīng)用中。Quartz框架只需要少數(shù)的第三方庫,并且這些三方庫是必需的,你很可能已經(jīng)在使用這些庫了。      你要把Quartz的安裝目錄的/lib/core 和 /lib/optional目錄中的第三方庫加進(jìn)你自己的工程中。大多數(shù)第三方庫是我們所熟知和喜歡的標(biāo)準(zhǔn)Jakarta Commons庫,像Commons Logging, Commons BeantUtils等等。      quartz.properties文件      Quartz有一個(gè)叫做quartz.properties的配置文件,它允許你修改框架運(yùn)行時(shí)環(huán)境。缺省是使用Quartz.jar里面的quartz.properties文件。當(dāng)然,你應(yīng)該創(chuàng)建一個(gè)quartz.properties文件的副本并且把它放入你工程的classes目錄中以便類裝載器找到它。quartz.properties樣本文件如例1所示。      例1.quartz.properties文件允許修改Quartz運(yùn)行環(huán)境:      #===============================================================   # Configure Main Scheduler Properties   #===============================================================   org.quartz.scheduler.instanceName = QuartzSchedulerorg.quartz.scheduler.instanceId = AUTO   #===============================================================   # Configure ThreadPool   #===============================================================   org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPoolorg.quartz.threadPool.threadCount = 5org.quartz.threadPool.threadPriority = 5   #===============================================================   # Configure JobStore   #===============================================================   org.quartz.jobStore.misfireThreshold = 60000org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore      一旦將Quartz.jar文件和第三方庫加到自己的工程里面并且quartz.properties文件在工程的classes目錄中,就可以創(chuàng)建作業(yè)了。然而,在做這之前,我們暫且回避一下先簡短討論一下Quartz架構(gòu)。      Quartz內(nèi)部架構(gòu)      在規(guī)模方面,Quartz跟大多數(shù)開源框架類似。大約有300個(gè)java類和接口,并被組織到12個(gè)包中。這可以和Apache Struts把大約325個(gè)類和接口以及組織到11個(gè)包中相比。盡管規(guī)模幾乎不會(huì)用來作為衡量框架質(zhì)量的一個(gè)特性,但這里的關(guān)鍵是quarts內(nèi)含很多功能,這些功能和特性集是否成為、或者應(yīng)該成為評(píng)判一個(gè)開源或非開源框架質(zhì)量的因素。      Quartz調(diào)度器      Quartz框架的核心是調(diào)度器。調(diào)度器負(fù)責(zé)管理Quartz應(yīng)用運(yùn)行時(shí)環(huán)境。調(diào)度器不是靠自己做所有的工作,而是依賴框架內(nèi)一些非常重要的部件。Quartz不僅僅是線程和線程管理。為確保可伸縮性,Quartz采用了基于多線程的架構(gòu)。啟動(dòng)時(shí),框架初始化一套worker線程,這套線程被調(diào)度器用來執(zhí)行預(yù)定的作業(yè)。這就是Quartz怎樣能并發(fā)運(yùn)行多個(gè)作業(yè)的原理。Quartz依賴一套松耦合的線程池管理部件來管理線程環(huán)境。本片文障中,我們會(huì)多次提到線程池管理,但Quartz里面的每個(gè)對(duì)象是可配置的或者是可定制的。所以,例如,如果你想要插進(jìn)自己線程池管理設(shè)施,我猜你一定能!      作業(yè)      用Quartz的行話講,作業(yè)是一個(gè)執(zhí)行任務(wù)的簡單java類。任務(wù)可以是任何java代碼。只需你實(shí)現(xiàn)org.quartz.Job接口并且在出現(xiàn)嚴(yán)重錯(cuò)誤情況下拋出JobExecutionException異常即可。Job接口包含唯一的一個(gè)方法execute(),作業(yè)從這里開始執(zhí)行。一旦實(shí)現(xiàn)了Job接口和execute()方法,當(dāng)Quartz確定該是作業(yè)運(yùn)行的時(shí)候,它將調(diào)用你的作業(yè)。Execute()方法內(nèi)就完全是你要做的事情。下面有一些你要在作業(yè)里面做事情的例子:      · 用JavaMail(或者用其他的像Commons Net一樣的郵件框架)發(fā)送郵件   · 創(chuàng)建遠(yuǎn)程接口并且調(diào)用在EJB上的方法   · 獲取Hibernate Session,查詢和更新關(guān)系數(shù)據(jù)庫里的數(shù)據(jù)   · 使用OSWorkflow并且從作業(yè)調(diào)用一個(gè)工作流   · 使用FTP和到處移動(dòng)文件   · 調(diào)用Ant構(gòu)建腳本開始預(yù)定構(gòu)建      這種可能性是無窮的,正事這種無限可能性使得框架功能如此強(qiáng)大。Quartz給你提供了一個(gè)機(jī)制來建立具有不同粒度的、可重復(fù)的調(diào)度表,于是,你只需創(chuàng)建一個(gè)java類,這個(gè)類被調(diào)用而執(zhí)行任務(wù)。      作業(yè)管理和存儲(chǔ)      作業(yè)一旦被調(diào)度,調(diào)度器需要記住并且跟蹤作業(yè)和它們的執(zhí)行次數(shù)。如果你的作業(yè)是30分鐘后或每30秒調(diào)用,這不是很有用。事實(shí)上,作業(yè)執(zhí)行需要非常準(zhǔn)確和即時(shí)調(diào)用在被調(diào)度作業(yè)上的execute()方法。Quartz通過一個(gè)稱之為作業(yè)存儲(chǔ)(JobStore)的概念來做作業(yè)存儲(chǔ)和管理。      有效作業(yè)存儲(chǔ)      Quartz提供兩種基本作業(yè)存儲(chǔ)類型。第一種類型叫做RAMJobStore,它利用通常的內(nèi)存來持久化調(diào)度程序信息。這種作業(yè)存儲(chǔ)類型最容易配置、構(gòu)造和運(yùn)行。對(duì)許多應(yīng)用來說,這種作業(yè)存儲(chǔ)已經(jīng)足夠了。然而,因?yàn)檎{(diào)度程序信息是存儲(chǔ)在被分配給JVM的內(nèi)存里面,所以,當(dāng)應(yīng)用程序停止運(yùn)行時(shí),所有調(diào)度信息將被丟失。如果你需要在重新啟動(dòng)之間持久化調(diào)度信息,則將需要第二種類型的作業(yè)存儲(chǔ)。      第二種類型的作業(yè)存儲(chǔ)實(shí)際上提供兩種不同的實(shí)現(xiàn),但兩種實(shí)現(xiàn)一般都稱為JDBC作業(yè)存儲(chǔ)。兩種JDBC作業(yè)存儲(chǔ)都需要JDBC驅(qū)動(dòng)程序和后臺(tái)數(shù)據(jù)庫來持久化調(diào)度程序信息。這兩種類型的不同在于你是否想要控制數(shù)據(jù)庫事務(wù)或這釋放控制給應(yīng)用服務(wù)器例如BEA's WebLogic或Jboss。(這類似于J2EE領(lǐng)域中,Bean管理的事務(wù)和和容器管理事務(wù)之間的區(qū)別)      這兩種JDBC作業(yè)存儲(chǔ)是:      ·JobStoreTX:當(dāng)你想要控制事務(wù)或工作在非應(yīng)用服務(wù)器環(huán)境中是使用   ·JobStoreCMT:當(dāng)你工作在應(yīng)用服務(wù)器環(huán)境中和想要容器控制事務(wù)時(shí)使用。      JDBC作業(yè)存儲(chǔ)為需要調(diào)度程序維護(hù)調(diào)度信息的用戶而設(shè)計(jì)。      作業(yè)和觸發(fā)器      Quartz設(shè)計(jì)者做了一個(gè)設(shè)計(jì)選擇來從調(diào)度分離開作業(yè)。Quartz中的觸發(fā)器用來告訴調(diào)度程序作業(yè)什么時(shí)候觸發(fā)。框架提供了一把觸發(fā)器類型,但兩個(gè)最常用的是SimpleTrigger和CronTrigger。SimpleTrigger為需要簡單打火調(diào)度而設(shè)計(jì)。典型地,如果你需要在給定的時(shí)間和重復(fù)次數(shù)或者兩次打火之間等待的秒數(shù)打火一個(gè)作業(yè),那么SimpleTrigger適合你。另一方面,如果你有許多復(fù)雜的作業(yè)調(diào)度,那么或許需要CronTrigger。      CronTrigger是基于Calendar-like調(diào)度的。當(dāng)你需要在除星期六和星期天外的每天上午10點(diǎn)半執(zhí)行作業(yè)時(shí),那么應(yīng)該使用CronTrigger。正如它的名字所暗示的那樣,CronTrigger是基于Unix克隆表達(dá)式的。      作為一個(gè)例子,下面的Quartz克隆表達(dá)式將在星期一到星期五的每天上午10點(diǎn)15分執(zhí)行一個(gè)作業(yè)。      0 15 10 ? * MON-FRI      下面的表達(dá)式      0 15 10 ? * 6L 2002-2005      將在2002年到2005年的每個(gè)月的最后一個(gè)星期五上午10點(diǎn)15分執(zhí)行作業(yè)。      你不可能用SimpleTrigger來做這些事情。你可以用兩者之中的任何一個(gè),但哪個(gè)跟合適則取決于你的調(diào)度需要。      調(diào)度一個(gè)作業(yè)      讓我們通過看一個(gè)例子來進(jìn)入實(shí)際討論。現(xiàn)假定你管理一個(gè)部門,無論何時(shí)候客戶在它的FTP服務(wù)器上存儲(chǔ)一個(gè)文件,都得用電子郵件通知它。我們的作業(yè)將用FTP登陸到遠(yuǎn)程服務(wù)器并下載所有找到的文件。然后,它將發(fā)送一封含有找到和下載的文件數(shù)量的電子郵件。這個(gè)作業(yè)很容易就幫助人們整天從手工執(zhí)行這個(gè)任務(wù)中解脫出來,甚至連晚上都無須考慮。我們可以設(shè)置作業(yè)循環(huán)不斷地每60秒檢查一次,而且工作在7×24模式下。這就是Quartz框架完全的用途。      首先創(chuàng)建一個(gè)Job類,將執(zhí)行FTP和Email邏輯。下例展示了Quartz的Job類,它實(shí)現(xiàn)了org.quartz.Job接口。      例2.從FTP站點(diǎn)下載文件和發(fā)送email的Quartz作業(yè)      public class ScanFTPSiteJob implements Job {   private static Log logger = LogFactory.getLog(ScanFTPSiteJob.class);   /*   * Called the scheduler framework at the right time   */  public void execute(JobExecutionContext context)   throws JobExecutionException {   JobDataMap jobDataMap = context.getJobDataMap();   try {   // Check the ftp site for files   File[] files = JobUtil.checkForFiles(jobDataMap);   JobUtil.sendEmail(jobDataMap, files);   } catch (Exception ex) {   throw new JobExecutionException(ex.getMessage());   }   }}      我們故意讓ScanFTPSiteJob保持很簡單。我們?yōu)檫@個(gè)例子創(chuàng)建了一個(gè)叫做JobUtil的實(shí)用類。它不是Quartz的組成部分,但對(duì)構(gòu)建各種作業(yè)能重用的實(shí)用程序庫來說是有意義的。我們可以輕易將那種代碼組織進(jìn)作業(yè)類中,quarts 調(diào)度器一樣好用,因?yàn)槲覀円恢痹谑褂胵uarts,所以那些代碼可繼續(xù)重用。      JobUtil.checkForFiles() and JobUtil.sendEmail()方法使用的參數(shù)是Quartz創(chuàng)建的JobDataMap的實(shí)例。實(shí)例為每個(gè)作業(yè)的執(zhí)行而創(chuàng)建,它是向作業(yè)類傳遞配置參數(shù)的方法。      這里并沒有展示JobUtil的實(shí)現(xiàn),但我們能用Jakarta上的Commons Net輕易地實(shí)現(xiàn)FTP和Email功能。      用調(diào)度器調(diào)用作業(yè)      首先創(chuàng)建一個(gè)作業(yè),但為使作業(yè)能被調(diào)度器調(diào)用,你得向調(diào)度程序說明你的作業(yè)的調(diào)用時(shí)間和頻率。這個(gè)事情由與作業(yè)相關(guān)的觸發(fā)器來完成。因?yàn)槲覀儍H僅對(duì)大約每60秒循環(huán)調(diào)用作業(yè)感興趣,所以打算使用SimpleTrigger。      作業(yè)和觸發(fā)器通過Quartz調(diào)度器接口而被調(diào)度。我們需要從調(diào)度器工廠類取得一個(gè)調(diào)度器的實(shí)例。最容易的辦法是調(diào)用StdSchedulerFactory這個(gè)類上的靜態(tài)方法getDefaultScheduler()。      使用Quartz框架,你需要調(diào)用start()方法來啟動(dòng)調(diào)度器。例3的代碼遵循了大多數(shù)Quartz應(yīng)用的一般模式:創(chuàng)建一個(gè)或多個(gè)作業(yè),創(chuàng)建和設(shè)置觸發(fā)器,用調(diào)度器調(diào)度作業(yè)和觸發(fā)器,啟動(dòng)調(diào)度器。      例3.Quartz作業(yè)通過Quartz調(diào)度器而被調(diào)度      public class MyQuartzServer {   public static void main(String[] args) {   MyQuartzServer server = new MyQuartzServer();   try {   server.startScheduler();   } catch (SchedulerException ex) {   ex.printStackTrace();   }   }   protected void startScheduler() throws SchedulerException {   // Use the factory to create a Scheduler instance   Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();   // JobDetail holds the definition for Jobs   JobDetail jobDetail = new JobDetail("ScanFTPJob", Scheduler.DEFAULT_GROUP,   ScanFTPSiteJob.class);// Store job parameters to be used within execute()jobDetail.getJobDataMap().put("FTP_HOST", "\\home\\cavaness\\inbound");   // Other neccessary Job parameters here   // Create a Trigger that fires every 60 seconds   Trigger trigger = TriggerUtils.makeSecondlyTrigger(60);   // Setup the Job and Trigger with the Scheduler   scheduler.scheduleJob(jobDetail, trigger );   // Start the Scheduler running   scheduler.start();   }}      編程調(diào)度同聲明性調(diào)度      例3中,我們通過編程的方法調(diào)度我們的ScanFTPSiteJob作業(yè)。就是說,我們用java代碼來設(shè)置作業(yè)和觸發(fā)器。Quartz框架也支持在xml文件里面申明性的設(shè)置作業(yè)調(diào)度。申明性方法允許我們更快速地修改哪個(gè)作業(yè)什么時(shí)候被執(zhí)行。      Quartz框架有一個(gè)插件,這個(gè)插件負(fù)責(zé)讀取xml配置文件。xml配置文件包含了關(guān)于啟動(dòng)Quartz應(yīng)用的作業(yè)和觸發(fā)器信息。所有xml文件中的作業(yè)連同相關(guān)的觸發(fā)器都被加進(jìn)調(diào)度器。你仍然需要編寫作業(yè)類,但配置那些作業(yè)類的調(diào)度器則非常動(dòng)態(tài)化。例4展示了一個(gè)用申明性方式執(zhí)行與例3代碼相同的邏輯的xml配置文件。      例4.能使用xml文件調(diào)度的作業(yè)               ScanFTPSiteJob   DEFAULT      A job that scans an ftp site for files      ScanFTPSiteJob         FTP_HOST   \home\cavaness\inbound                     ScanFTPSiteJobTrigger   DEFAULT   ScanFTPSiteJob   DEFAULT   2005-09-11 6:10:00 PM      -1   60000               你可以將xml文件中的元素跟例3代碼作個(gè)比較,它們從概念上來看是相同的。使用例4式的申明性方法的好處是維護(hù)變得極其簡單,只需改變xml配置文件和重新啟動(dòng)Quartz應(yīng)用即可。無須修改代碼,無須重新編譯,無須重新部署。      有狀態(tài)和無狀態(tài)作業(yè)      在本文中你所看到的作業(yè)到是無狀態(tài)的。這意味著在兩次作業(yè)執(zhí)行之間,不會(huì)去維護(hù)作業(yè)執(zhí)行時(shí)JobDataMap的狀態(tài)改變。如果你需要能增、刪,改JobDataMap的值,而且能讓作業(yè)在下次執(zhí)行時(shí)能看到這個(gè)狀態(tài)改變,則需要用Quartz有狀態(tài)作業(yè)。      如果你是一個(gè)有經(jīng)驗(yàn)的EJB開發(fā)者的話,深信你會(huì)立即退縮,因?yàn)橛袪顟B(tài)帶有負(fù)面含義。這主要是由于EJB帶來的伸縮性問題。Quartz有狀態(tài)作業(yè)實(shí)現(xiàn)了org.quartz.StatefulJob接口。無狀態(tài)和有狀態(tài)作業(yè)的關(guān)鍵不同是有狀態(tài)作業(yè)在每次執(zhí)行時(shí)只有一個(gè)實(shí)例。大多數(shù)情況下,有狀態(tài)的作業(yè)不回帶來大的問題。然而,如果你有一個(gè)需要頻繁執(zhí)行的作業(yè)或者需要很長時(shí)間才能完成的作業(yè),那么有狀態(tài)作業(yè)可能給你帶來伸縮性問題。      Quartz框架的其他特征      Quartz框架有一個(gè)豐富的特征集。事實(shí)上,quarts有太多特性以致不能在一種情況中全部領(lǐng)會(huì),下面列出了一些有意思的特征,但沒時(shí)間在此詳細(xì)討論。      監(jiān)聽器和插件      每個(gè)人都喜歡監(jiān)聽和插件。今天,幾乎下載任何開源框架,你必定會(huì)發(fā)現(xiàn)支持這兩個(gè)概念。監(jiān)聽是你創(chuàng)建的java類,當(dāng)關(guān)鍵事件發(fā)生時(shí)會(huì)收到框架的回調(diào)。例如,當(dāng)一個(gè)作業(yè)被調(diào)度、沒有調(diào)度或觸發(fā)器終止和不再打火時(shí),這些都可以通過設(shè)置來來通知你的監(jiān)聽器。Quartz框架包含了調(diào)度器監(jiān)聽、作業(yè)和觸發(fā)器監(jiān)聽。你可以配置作業(yè)和觸發(fā)器監(jiān)聽為全局監(jiān)聽或者是特定于作業(yè)和觸發(fā)器的監(jiān)聽。      一旦你的一個(gè)具體監(jiān)聽被調(diào)用,你就能使用這個(gè)技術(shù)來做一些你想要在監(jiān)聽類里面做的事情。例如,你如果想要在每次作業(yè)完成時(shí)發(fā)送一個(gè)電子郵件,你可以將這個(gè)邏輯寫進(jìn)作業(yè)里面,也可以JobListener里面。寫進(jìn)JobListener的方式強(qiáng)制使用松耦合有利于設(shè)計(jì)上做到更好。      Quartz插件是一個(gè)新的功能特性,無須修改Quartz源碼便可被創(chuàng)建和添加進(jìn)Quartz框架。他為想要擴(kuò)展Quartz框架又沒有時(shí)間提交改變給Quartz開發(fā)團(tuán)隊(duì)和等待新版本的開發(fā)人員而設(shè)計(jì)。如果你熟悉Struts插件的話,那么完全可以理解Quartz插件的使用。      與其Quartz提供一個(gè)不能滿足你需要的有限擴(kuò)展點(diǎn),還不如通過使用插件來擁有可修整的擴(kuò)展點(diǎn)。      集群Quartz應(yīng)用      Quartz應(yīng)用能被集群,是水平集群還是垂直集群取決于你自己的需要。集群提供以下好處:      ·伸縮性   ·搞可用性   ·負(fù)載均衡      目前,Quartz只能借助關(guān)系數(shù)據(jù)庫和JDBC作業(yè)存儲(chǔ)支持集群。將來的版本這個(gè)制約將消失并且用RAMJobStore集群將是可能的而且將不需要數(shù)據(jù)庫的支持。      Quartz web應(yīng)用      使用框架幾個(gè)星期或幾個(gè)月后,Quartz用戶所顯示的需求之一是需要集成Quartz到圖形用戶界面中。目前Quartz框架已經(jīng)有一些工具允許你使用Java servlet來初始化和啟動(dòng)Quartz。一旦你可以訪問調(diào)度器實(shí)例,你就可以把它存儲(chǔ)在web容器的servlet上下文中(ServletContext中)并且可以通過調(diào)度器接口管理調(diào)度環(huán)境。      幸運(yùn)的是一些開發(fā)者已正影響著單機(jī)Quartz web應(yīng)用,它用來更好地管理調(diào)度器環(huán)境。構(gòu)建在若干個(gè)流行開源框架如Struts和Spring之上的圖形用戶界面支持很多功能,這些功能都被包裝進(jìn)一個(gè)簡單接口。GUI的一個(gè)畫面如圖1所示:       圖1.Quartz Web應(yīng)用允許比較容易地管理Quartz環(huán)境。      Quartz的下一步計(jì)劃      Quartz是一個(gè)活動(dòng)中的工程。Quartz開發(fā)團(tuán)隊(duì)明確表示不會(huì)停留在已有的榮譽(yù)上。Quartz下一個(gè)主要版本已經(jīng)在啟動(dòng)中。你可以在OpenSymphony的 wiki上體驗(yàn)一下Quartz 2.0的設(shè)計(jì)和特征。      總之,Quartz用戶每天都自由地添加特性建議和設(shè)計(jì)創(chuàng)意以便能被核心框架考慮(看重)。