close
  在一個應用系統中常要定時去執行某些程式, 例如: 同步異質平台的資料, 或是定時發信件; Java是一種跨平台(Window/Linux)的程式語言, 雖然在 Window 平台可以用 AT 指令來作排程, 在 Linux 可以用 crontab 來排程, 但總是無法與系統作密切的結合.
quartz是個不錯的選擇, 它一樣可以跨異質平台作業, 而且與 Java 的結合也很密切, 只要在Java程式段有

public void execute(JobExecutionContext context)
throws JobExecutionException {....}

quartz作接口即可
, 下面我們來看一下如何實作它.總共有幾個步驟, 就可以讓它順利執行.
設定
1. 下載 quartz 所需的 JAR 檔
2. WEB-INF/web.xml 中加入quartz的 servlet

<servlet>
<servlet-name>QuartzInitializer</servlet-name>
<servlet-class>
org.quartz.ee.servlet.QuartzInitializerServlet
</servlet-class>
<init-param>
<param-name>config-file</param-name>
<param-value>/quartz.properties</param-value>
</init-param>
<init-param>
<param-name>shutdown-on-unload</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>start-scheduler-on-load</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>

3. 建立 quartz的設定檔
  在 Java Resource 的目錄建立二個檔案 quartz.properties 及 jobSchedule.xml(此檔的檔名可以自定), 檔案內容如下:
quartz.properties 檔

org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
org.quartz.jobStore.misfireThreshold=60000
org.quartz.plugin.jobInitializer.class=org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.failOnFileNotFound=true
org.quartz.plugin.jobInitializer.fileName=/jobSchedule.xml => 這個檔案是定義 JOB 的排程用
org.quartz.plugin.jobInitializer.overWriteExistingJobs=true
org.quartz.plugin.jobInitializer.validating=false
org.quartz.plugin.jobInitializer.validatingSchema=true
org.quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingTriggerHistoryPlugin
org.quartz.plugin.triggHistory.triggerCompleteMessage=Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH\:mm\:ss MM/dd/yyyy} with resulting trigger instruction code\: {9}
org.quartz.plugin.triggHistory.triggerFiredMessage=Trigger {1}.{0} fired job {6}.{5} at\: {4, date, HH\:mm\:ss MM/dd/yyyy}
org.quartz.scheduler.instanceId=1
org.quartz.scheduler.instanceName=sched1
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=100
org.quartz.threadPool.threadPriority=5

jobSchedule.xml 檔

<?xml version="1.0" encoding="UTF-8"?>
<quartz>
<job>
<job-detail>
<name>job_mail_demo</name> ==> 定義工作的名字: job_mail_demo
<group>DEFAULT</group>
<description>job_mail_demo</description>
<job-class>com.demos.job_mail_demo</job-class> ==> 定義排程器要執行那一個 Java 程式
<job-data-map allows-transient-data="true">
<entry>
<key>name</key>
<value>job_mail_demo</value>
</entry>
</job-data-map>
</job-detail>
<trigger>
<cron>
<name>Cron_job_mail</name> ==> 定義排程器的名字: Cron_job_mail
<group>DEFAULT</group>
<job-name>job_mail_demo</job-name> ==> 定義排程器[Cron_job_mail]內要執行的工作[job_mail_demo]
<job-group>DEFALUT</job-group>
<cron-expression>0 0/5 * * * ?</cron-expression> ==> 每5分鐘執行工作排程 job_mail_demo 一次
</cron>
</trigger>
</job>
</quartz>
<!-- Cron 的小小說明表示方式意義
CronTrigger配置格式:

格式: [秒] [分] [小時] [日] [月] [周] [年]

序号

說明 

是否必填

允许填寫的值

允许的通配符  

1

0-59 

  , - * /

2

0-59
 

  , - * /

3

小時

0-23

  , - * /

4

1-31

  , - * ? / L W

5

1-12 or JAN-DEC

  , - * /

6

星期

1-7 or SUN-SAT

  , - * ? / L #

7

empty 或 1970-2099

, - * /

配置符號說明:

*

表示所有值. 例如:在分的字段上設定 "*",表示每一分鐘都會觸發。
? 表示不指定值。使用的場景為不需要關心當前設定這個字段的值。例如:要在每月的10號觸發一個操作,但不論是禮拜幾,所以需要星期位置的那個字段設置為"?" 具體設置為 0 0 0 10 * ?
- 表示區間。例如 在小時上設定 "10-12",表示 10,11,12點都會觸發。
, 表示指定多個值,例如在星期字段上設定 "MON,WED,FRI" 表示周一,周三和周五觸發。
/ 用於遞增觸發。如在秒上面設定"5/15" 表示從5秒開始,每增加15秒觸發(5,20,35,50)。 在月字段上設定'1/3'所示每月1號開始,每隔三天觸發一次。
L 表示最後的意思。在日字段設定上,表示當月的最後一天(依據當前月份,如果是二月還會依據是否是潤年[leap]), 在星期字段上表示星期六,相當於"7"或"SAT"。如果在"L"前加上數字,則表示該數據的最後一个。例如在星期字段上設定"6L"這樣的格式,則表示“本月最後一個星期五"。
W 表示離指定日期的最近那個工作日(周一至周五). 例如在日字段上設定"15W",表示離每月15號最近的那個工作日觸發。如果15號正好是周六,則找最近的周五(14號)觸發, 如果15號是周未,則找最近的下周一(16號)觸發.如果15號正好在工作日(周一至周五),則就在當天觸發。如果指定格式為 "1W",它則表示每月1號往後最近的工作日觸發。如果1號正是周六,則將在3號下周一觸發。(註,"W"前只能設定具體的數字,不允許區間"-")。
# 序號(表示每月的第幾個星期幾),例如在星期字段上設定"6#3"表示在每月的第三個周六.注意如果指定"#5",正好第五周沒有周六,則不會觸發該設定(用在母親節和父親節再合適不過了) 。

P.S:'L'和 'W'可以組合使用。如果在日字段上設定"LW",則表示在本月的最後一個工作日觸發(一般指發工資 ) 。

P.S:周字段的設定,若使用英文字母是不區分大小寫的 MON 與mon相同。"0 0 12 * * ?" Fire at 12pm (noon) every day
"0 15 10 ? * *" Fire at 10:15am every day
"0 15 10 * * ?" Fire at 10:15am every day
"0 15 10 * * ? *" Fire at 10:15am every day
"0 15 10 * * ? 2005" Fire at 10:15am every day during the year 2005
"0 * 14 * * ?" Fire every minute starting at 2pm and ending at 2:59pm, every day
"0 0/5 14 * * ?" Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day
"0 0/5 14,18 * * ?" Fire every 5 minutes starting at 2pm and ending at 2:55pm, AND fire every 5 minutes starting at 6pm and ending at 6:55pm, every day
"0 0-5 14 * * ?" Fire every minute starting at 2pm and ending at 2:05pm, every day
"0 10,44 14 ? 3 WED" Fire at 2:10pm and at 2:44pm every Wednesday in the month of March.
"0 15 10 ? * MON-FRI" Fire at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday
"0 15 10 15 * ?" Fire at 10:15am on the 15th day of every month
"0 15 10 L * ?" Fire at 10:15am on the last day of every month
"0 15 10 ? * 6L" Fire at 10:15am on the last Friday of every month
"0 15 10 ? * 6L" Fire at 10:15am on the last Friday of every month
"0 15 10 ? * 6L 2002-2005" Fire at 10:15am on every last friday of every month during the years 2002, 2003, 2004 and 2005
"0 15 10 ? * 6#3" Fire at 10:15am on the third Friday of every month
-->

4. Java 程式段 job_mail_demo.java

package com.demos;
import java.sql.Connection;
import java.util.Date;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.gu.utils.BA_TOOLS;
public class job_mail_demo implements Job{
static Logger loger = Logger.getLogger(job_mail_demo.class.getName());
public void execute(JobExecutionContext context)
throws JobExecutionException {
String name = context.getJobDetail().getJobDataMap().getString("name");
System.out.println("run " + name + " at " + new java.util.Date());
loger.warn("Executing job: executing at " + new Date());
try {
BA_TOOLS tools = BA_TOOLS.getInstance();
tools.sendmail("localhost", "polin.wei@mail.com", "polin.wei@mail.com", "Schedule Job Demo",
"Schedule Job Demo");
System.out.println("END " + name + " at " + new java.util.Date());
loger.warn("job END: END at " + new Date());
} catch (Exception e) {
e.printStackTrace();
}
}
}

  系統執行時, quartz 就會依照排程定時去發 mail , 因為在 Java 程式有設 log4j 來作偵測 quartz 是否有定時執行, 所以可以看到 Java Console 的顯示如下:

[ERROR] 04 十一月 06:10:05.456 下午 Thread-8 [com.gu.utils.MailThread-run]
polin.wei@xxx.com郵件送出失敗!
2008/11/4 下午 06:15:00 org.quartz.plugins.history.LoggingTriggerHistoryPlugin triggerComplete
資訊: Trigger DEFAULT.Cron_job_mail completed firing job DEFAULT.job_mail_demo at 18:15:00 11/04/2008 with resulting trigger instruction code: DO NOTHING
[DEBUG] 04 十一月 06:15:05.679 下午 Thread-8 [com.gu.utils.MailThread-run]
polin.wei@mail.com郵件已送出!

參照自:http://polinwei.blogspot.com/2008/11/java-quartz.html

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 楊 bey kuen 的頭像
    楊 bey kuen

    楊 bey kuen的部落格

    楊 bey kuen 發表在 痞客邦 留言(0) 人氣()