1. 程式人生 > >Cron 觸發器及相關內容 (第一部分)

Cron 觸發器及相關內容 (第一部分)

我們在上章中有承諾過會花更多時間來講 Quartz 的 CronTrigger,所以不會讓你失望的。SimpleTrigger 對於需要在指定的毫秒處及時執行的作業還是不錯的,但是假如你的作業需要更復雜的執行計劃時,你也就要 CronTrigger 給你提供更強更靈活的功能。
一. Cron 的快速一課
cron 這一觀念是來自於 UNIX 世界。在 UNIX 中,cron 是一個運行於後臺的守護程式,它負責所有基於時間的事件。儘管 Quartz 除相同的名字和相似的表示式語法外,並未分享到 UNIX cron 別的東西,我們還是值得花幾個段落去理解 cron 背後的歷史。我們這裡的目標不是搞混 UNIX cron 表示式和 Quartz 的 cron 表示式,但是你應該瞭解 Quartz 表示式的歷史,並探索為什麼他們運作起來很像。這兒明顯有許多有意圖的相似性。

有許多不同版本的 UNIX Cron
你會發現不同版本的 cron,每一種都有些微地差異。我們僅著眼於與 Quartz CronTrigger 的比較,因此我們只討論不同版本 UNIX cron 共性的東西。

UNIX cron 守護程序每隔一分鐘被喚醒一次去檢查叫做 crontabs 的配置檔案。(Crontab 是 CRON 和 TABLE 的連寫,其中配置有 cron 守護程序的作業列表和其他的指令。)守護程序檢查儲存在 crontabs 中的命令並決定是否有要執行的任務。
·UNIX Cron 的格式
你可以認為 UNIX crontab 是 Trigger 和 Job 的組合,因為它們同時列出來執行計劃和要執行的命令(job)。
Cron Expression 的格式


crontab 格式包含六段,前五段為執行計劃,第六段為要執行的命令。(Quartz cron 表示式有七段。) 下面這些是執行計劃的五個欄位:
    ·分 (00-59)
    ·時 (00-23)
    ·日 (1-31)
    ·月 (1-12)
    ·周 (0-6 或 sun-sat)
UNIX cron 格式表示式中允許出現一些特殊的字元,例如星號(*),它用來匹配所有值。這作有一個 UNIX crontab 的例子:
0 8 * * * echo "WAKE UP" 2>$1 /dev/console
這一 crontab 條目在每天早上8點列印字串 "WAKE UP" 到 UNIX 的設定 /dev/console 上。圖 5.1 顯示了這個動作。

UNIX Cron 執行 0 8 * * * echo "WAKE UP" 2>$1 /dev/console  表示式

2. 使用 Quartz CronTrigger

在現實世界裡,作業計劃通常比 SimpleTrigger 能支援的複雜得多。CronTrigger 就可用於指定非常複雜的計劃,這種計劃不錯,因為也是我們發現需要這麼做的。在我們深入到 CronTrigger 之前,讓我們先看一個例子。程式碼 5.1 所示的是一個使用 CronTrigger (連同一個 Quartz cron 表示式) 來部署前面例子中的 PrintInfoJob。程式碼中的大部分內容與前面章節的例子相同。唯一不同點是我們使用了 CronTrigger 替代了 SimpleTrigger。正因為如此,我們不得不為它提供了一個 cron 表示式。
程式碼 5.1. 簡單使用 CronTrigger 來部署一個 Job

  1. public class Listing_5_1 {  
  2. static Log logger = LogFactory.getLog(Listing_5_1.class);  
  3. public static void main(String[] args) {  
  4.           Listing_5_1 example = new Listing_5_1();  
  5.           example.runScheduler();  
  6.      }  
  7. public void runScheduler() {  
  8.           Scheduler scheduler = null;  
  9. try {  
  10. // Create a default instance of the Scheduler
  11.               scheduler = StdSchedulerFactory.getDefaultScheduler();  
  12.               scheduler.start();  
  13.               logger.info("Scheduler was started at " + new Date());  
  14. // Create the JobDetail
  15.               JobDetail jobDetail =  
  16. new JobDetail("PrintInfoJob",  
  17.                         Scheduler.DEFAULT_GROUP,  
  18.                                     PrintInfoJob.class);  
  19. // Create a CronTrigger
  20. try {  
  21. // CronTrigger that fires @7:30am Mon - Fri
  22.                    CronTrigger trigger = new
  23.                                     CronTrigger("CronTrigger", null,  
  24. "0 30 7 ? * MON-FRI");  
  25.                    scheduler.scheduleJob(jobDetail, trigger);  
  26.               } catch (ParseException ex) {  
  27.                    logger.error("Error parsing cron expr", ex);  
  28.               }  
  29.          } catch (SchedulerException ex) {  
  30.               logger.error(ex);  
  31.         }  
  32.     }  

public class Listing_5_1 { static Log logger = LogFactory.getLog(Listing_5_1.class); public static void main(String[] args) { Listing_5_1 example = new Listing_5_1(); example.runScheduler(); } public void runScheduler() { Scheduler scheduler = null; try { // Create a default instance of the Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); logger.info("Scheduler was started at " + new Date()); // Create the JobDetail JobDetail jobDetail = new JobDetail("PrintInfoJob", Scheduler.DEFAULT_GROUP, PrintInfoJob.class); // Create a CronTrigger try { // CronTrigger that fires @7:30am Mon - Fri CronTrigger trigger = new CronTrigger("CronTrigger", null, "0 30 7 ? * MON-FRI"); scheduler.scheduleJob(jobDetail, trigger); } catch (ParseException ex) { logger.error("Error parsing cron expr", ex); } } catch (SchedulerException ex) { logger.error(ex); } } }
程式碼 5.1 中的例子使用瞭如下 cron 表示式:
0 30 7 ? * MON-FRI
當被排程器解釋後,它會引起 Trigger 在星期一至星期五的早上 7:30 被激發。讓我們來看看 Quartz CronTrigger 的 cron 表示式的格式。