Quartz 是 OpenSymphony 開源的企業級排程框架,支援 Cron 觸發器、Simple 觸發器等。本文示範在 J2EE 環境(以 Oracle OC4J 10g 為例)中,如何將 EJB 方法包裝為 Quartz 排程任務。
需求:每 30 分鐘自動執行一次特定業務邏輯。
建立 Stateless Session Bean TestEJB,封裝核心邏輯:
package howto.quartz.ejb;
import javax.ejb.*;
import java.rmi.RemoteException;
public class TestEJBBean implements SessionBean {
public void ejbCreate() throws CreateException {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext ctx) {}
public void yourMethod() throws RemoteException {
System.out.println("TestEJB Job executed at " + new java.util.Date());
// 實際業務邏輯:報表產生、資料同步、通知發送等
}
}
因 Quartz 使用自身執行緒池,不得在 EJB 中直接啟動排程。採用 Servlet 作為進入點:
package howto.quartz.servlet;
import javax.servlet.*;
import org.quartz.*;
import org.quartz.ee.jmx.*;
public class QuartzServlet extends GenericServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("Scheduling Job ...");
// 1. 定義 JobDetail,指向內建 EJBInvokerJob
JobDetail jd = new JobDetail("Test Quartz", "My Test Job", EJBInvokerJob.class);
jd.getJobDataMap().put("ejb", "java:comp/env/ejb/TestEJB"); // JNDI 名稱
jd.getJobDataMap().put("method", "yourMethod"); // 呼叫方法
jd.getJobDataMap().put("args", new Object[0]); // 參數陣列
// 2. CronTrigger:每 30 分鐘
CronTrigger cronTrigger = new CronTrigger("Test Quartz", "Test Quartz");
try {
String cronExpr = getInitParameter("cronExpr"); // 從 web.xml 讀取
System.out.println("Cron Expression: " + cronExpr);
cronTrigger.setCronExpression(cronExpr);
// 3. 向 Scheduler 註冊
Scheduler sched = StdSchedulerFactory.getDefaultScheduler();
sched.scheduleJob(jd, cronTrigger);
System.out.println("Job scheduled now ...");
} catch (Exception e) {
e.printStackTrace();
}
}
public void service(ServletRequest req, ServletResponse res)
throws ServletException, java.io.IOException {}
public String getServletInfo() { return null; }
}
| 類別 | 角色 |
|---|---|
QuartzInitializerServlet | Quartz 官方提供,啟動 Scheduler、載入 quartz.properties |
EJBInvokerJob | Quartz 內建 Job,透過 JNDI 查找 EJB 並反射呼叫指定方法 |
StdSchedulerFactory | 單例 Scheduler 工廠 |
0 0/30 * * * ? → 每 30 分鐘(第 0 秒、每 30 分鐘、每小時、每天、每月、任意星期)
* * * * * ? → 每秒(測試用)
0 0 2 * * ? → 每天凌晨 2 點
第二部分將涵蓋:
1. web.xml 完整配置(Servlet、ejb-ref、load-on-startup)
2. EAR 打包與庫依賴管理
3. 容器使用者執行緒啟用
4. 自動部署與驗證