Quartz 是來自OpenSymphony的一個開發源代碼的企業級工作計劃調度器。要了解詳情以及下載Quartz請訪問http://www.quartzscheduler.org/quartz/。你可以在你的J2EE應用如EJB中使用Quartz來調度工作計劃。本文將會介紹在你的J2EE應用中如何使用Quartz來安排工作計劃。文章中將會使用Oracle應用服務器10g J2EE容器(OC4J 9.0.4)作為J2EE容器的例子。
Quartz 支持多種類型的工作和觸發器,但其中最流行的就是cron級別的觸發器。要了解Quartz 工作計劃調度的兼容性,請參考Quartz 的文檔: http://www.quartzscheduler.org/quartz/docs.html。另外Dejan Bosanac 也寫了一篇非常好的文章Job Scheduling in Java 可能會對你有所幫助。
在我們進入細節論題之前,先假設你有一個業務案例,需要讓一項工作每30分鐘運行一次。在本文中我們將會討論如何使用Quartz的克龍級觸發器功能來做到這一點。
1 定義你的工作為EJB方法
在J2EE應用中使用計劃任務的第一步就是創建EJB並將業務邏輯封裝為EJB的方法。舉個例子,我創建了一個名稱為TestEJB的無狀態的EJB,其中有一個方法叫做yourMethod我需要定義為計劃任務。為了更清楚一點,下面我列舉了我的EJB的代碼片段和EJB部署描述:
package howto.quartz.ejb;
import java.rmi.*;
import javax.ejb.*;
public class TestEJBBean implements SessionBean {
public TestEJBBean() {
}
// EJB life cycle methods are omitted for brevity
........
public void yourMethod() throws RemoteException {
System.out.println("TestEJB Job");
}
}
2 從一個通常的Servlet使用Quartz API來定制你的計劃任務
Quartz 使用自己的線程池,這些線程並不是容器線程。Servlet API 允許用戶線程,並且因為你需要創建一個Servlet並使用Quartz API 來排定計劃任務。Quartz 提供了QuartzInitializerServlet 作為其工作計劃服務的入口。在本例中我們需要將TestEJB的yourMethod方法提交為工作任務。因此我們將創建一個GenericServlet 名稱為howto.quartz.servlet.QuartzServlet,並在init() 方法中將EJB 方法提交為一個克龍觸發器。在本例中,我將克龍表達式設置為初始化參數而不是采用在Servlet中硬編碼的方式。下面就是Servlet的代碼:
public class QuartzServlet extends GenericServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("Scheduling Job ..");
JobDetail jd = new JobDetail("Test Quartz","My Test Job",EJBInvokerJob.class);
jd.getJobDataMap().put("ejb", "java:comp/env/ejb/TestEJB");
jd.getJobDataMap().put("method", "yourMethod");
Object[] jdArgs = new Object[0];
jd.getJobDataMap().put("args", jdArgs);
CronTrigger cronTrigger = new CronTrigger("Test Quartz", "Test Quartz");
try {
String cronExpr = null;
// Get the cron Expression as an Init parameter
cronExpr = getInitParameter("cronExpr");
System.out.println(cronExpr);
cronTrigger.setCronExpression(cronExpr);
Scheduler sched = StdSchedulerFactory.getDefaultScheduler();
sched.scheduleJob(jd, cronTrigger);
System.out.println("Job scheduled now ..");
} catch (Exception e) {
e.printStackTrace();
}
}
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
}
public String getServletInfo() {
return null;
}
}