負責在預定時間自動執行或通知應用元件的系統。例:每週一 09:30 發送業務報表 Email。
java.util.Timer/TimerTask 功能單薄:不支援持久化、執行緒池、類 Cron 運算式、叢集高可用。quartz.jar 即可運作。Scheduler:排程/取消、啟動/暫停/關閉。JobListener, TriggerListener, SchedulerListener 完整監控執行生命週期。import java.util.Date;
import org.quartz.*;
public class SayHelloWorldJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello World! " + new Date());
}
public static void main(String[] args) throws Exception {
// 1. 取得 Scheduler
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
// 2. 定義 JobDetail (任務元資料)
JobDetail jobDetail = new JobDetail("SayHelloWorldJob",
Scheduler.DEFAULT_GROUP,
SayHelloWorldJob.class);
// 3. 定義 Trigger (觸發條件) — 立即執行一次
Trigger trigger = new SimpleTrigger("SayHelloWorldTrigger",
Scheduler.DEFAULT_GROUP,
new Date(), null, 0, 0L);
// 4. 註冊並啟動
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start(); // 關鍵:啟動排程執行緒
}
}
實作 org.quartz.Job 介面,唯一方法 execute(JobExecutionContext)。JobExecutionContext 提供執行時上下文:Scheduler, JobDetail, Trigger 等引用。
不可變資料物件,包含:
name + group:唯一識別 (同群組名稱不可重複)。jobClass:實際執行類別。JobDataMap:攜帶參數資料 (Key-Value),execute() 可取用。分離「任務」與「何時執行」:
| Trigger 類型 | 適用場景 | 關鍵參數 |
|---|---|---|
| SimpleTrigger | 固定間隔、特定次數、特定時間點 | repeatCount, repeatInterval |
| CronTrigger | 行事曆式排程 (每週五 15:00、每月最後一天) | cronExpression (Unix cron 語法) |
範例中 SimpleTrigger 參數:startTime=now, endTime=null, repeatCount=0, repeatInterval=0 → 立即執行一次。
scheduleJob(jobDetail, trigger):建立關聯。start():啟動內部執行緒池,開始評估 Trigger。group+name 唯一識別 Job/Trigger。jobDetail.getJobDataMap().put("emailFrom", "admin@example.com");
jobDetail.getJobDataMap().put("retryCount", 3);
// execute() 內取用
String from = context.getJobDetail().getJobDataMap().getString("emailFrom");
int retry = context.getJobDetail().getJobDataMap().getInt("retryCount");
限制:若使用 JDBC JobStore,JobDataMap 會被序列化儲存,**值必須實作 Serializable**;DataSource, Connection 等不可序列化物件無法直接存放。
// 啟動前註冊
scheduler.getContext().put("dataSource", myDataSource);
// Job 內取用
DataSource ds = (DataSource) context.getScheduler().getContext().get("dataSource");
適合資料庫連線池、快取管理器等非序列化、全域單例資源。