前言:
 在我前年剛開始寫程式,因為專案需求需要寫一支可以定時計算資料的排程。GOOGLE了許久,就決定用Quartz這個套件。當時的Quartz版本是1.6.x。需要在xml設定時間以及需要執行的程式,雖然好用,但卻很死,時間設定須寫死在xml檔,一但有更動時間,就必須將整包程式重新編譯、部署....。就在最近的新專案中,又有需求需要用到工作排程了,於是藉此機會順便研究更活的寫法,也終於讓我研究出來了(感動T_T,對一個程式新手來說,這成就感超大的阿︿( ̄︶ ̄)︿。廢話不多說,以下將我的用法記錄下來,順便分享給大家。


1.首先需要引入以下jar檔
quartz2.0.0.jar
jta.jar
commons-logging-1.1.jar
commons-collections3.2.jar

2.再來寫一個排程模組,以下是我的code

==================================================================

/**
* 排程控制模組
*
* @author Shan
*
*/
public class JobModule {

public static SchedulerFactory sf;
public static Scheduler sched;
public static CronTrigger trigger;
public static JobDetail jobDetail;
public static Map jobKeyMap;

static {

jobKeyMap = new HashMap ();
sf = new StdSchedulerFactory();

try {
sched = sf.getScheduler();
} catch (SchedulerException e) {
e.printStackTrace();
}
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public static void jobStart(JobScheduleSetting jobScheduleSetting){

String className = jobScheduleSetting.getClassName(); //要執行的class
String jobName = jobScheduleSetting.getJobName(); //工作名稱
String jobGroup = jobScheduleSetting.getGroupName(); //排程群組 一個群組可以設定多個工作
String triggerStr = jobScheduleSetting.getTriggerName(); //
String CronTime = jobScheduleSetting.getCronTime(); //時間 "秒 分 時 日 月 周 年"

Class c;
try {
c = Class.forName(className);

jobDetail = JobBuilder.newJob(c).withIdentity(jobName, jobGroup).build();
trigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity(triggerStr, jobGroup).withSchedule(CronScheduleBuilder.cronSchedule(CronTime)).build();

if(jobKeyMap.containsKey(jobName)){
sched.deleteJob((JobKey)jobKeyMap.get(jobName));
}

Date dt = sched.scheduleJob(jobDetail, trigger);

jobKeyMap.put(jobName, jobDetail.getKey());

System.out.println(jobName + " 排程啟動於... " + dt);

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SchedulerException e) {
e.printStackTrace();
}
}

public static void jobStop(JobScheduleSetting jobScheduleSetting){

try {
if (jobKeyMap.containsKey(jobScheduleSetting.getJobName())) {
sched.deleteJob((JobKey) jobKeyMap.get(jobScheduleSetting.getJobName()));
}
System.out.println(jobScheduleSetting.getJobName() + " 排程已停止... " + new Date());
} catch (SchedulerException e) {
e.printStackTrace();
}
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {

System.out.println("test gogo");

SchedulerFactory sf = new StdSchedulerFactory();

String className = "com.mitac.backend.jobSchedules.JobTest"; //要執行的class
String jobName = "JobTest"; //工作名稱
String jobGroup = "gropp1"; //排程群組 一個群組可以設定多個工作
String triggerStr = "trigger0"; //
String CronTime = "0 26 12 * * ?"; //時間 "秒 分 時 日 月 周 年"

String className_2 = "com.mitac.backend.jobSchedules.JobTest2"; //要執行的class
String jobName_2 = "JobTest2"; //工作名稱
String jobGroup_2 = "gropp1"; //排程群組 一個群組可以設定多個工作
String triggerStr_2 = "trigger1"; //
String CronTime_2 = "0 26 12 * * ?"; //時間 "秒 分 時 日 月 周 年"

try {
Scheduler sched = sf.getScheduler();

Class c = Class.forName(className);
JobDetail jobDetail = JobBuilder.newJob(c).withIdentity(jobName, jobGroup).build();
CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity(triggerStr, jobGroup).withSchedule(CronScheduleBuilder.cronSchedule(CronTime)).build();

Date dt = sched.scheduleJob(jobDetail, trigger);

System.out.println("排程1開始於..... " + dt);

JobKey jobKey = jobDetail.getKey();

System.out.println(jobKey);
System.out.println(jobKey.getName());

c = Class.forName(className_2);

jobDetail = JobBuilder.newJob(c).withIdentity(jobName_2, jobGroup_2).build();
trigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity(triggerStr_2, jobGroup_2).withSchedule(CronScheduleBuilder.cronSchedule(CronTime_2)).build();

Date dt_2 = sched.scheduleJob(jobDetail, trigger);

System.out.println("排程2開始於..... " + dt_2);

sched.start();

jobKey = jobDetail.getKey();

System.out.println(jobKey);
System.out.println(jobKey.getName());

sched.deleteJob(jobKey);

} catch (SchedulerException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

==================================================================

我在測試的時候有發現 上面的 sched.start() 並不是指排程開始啟動,應該是指 Scheduler活起來的意思,所以在sched.start()後面再加上其他排程 sched.scheduleJob(jobDetail, trigger); 一樣會執行後面的工作。所以我們可以在 sched.start() 後再繼續增加其他工作都沒問題。

接著寫要執行的工作,實作Job這個介面,然後Override execute 這個方法,Scheduler會去執行裡面的程式
==================================================================

public class JobTest implements Job {

@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {

System.out.println("排程開始...........");

System.out.println("JobTest1 Hello World!");
}

}

==================================================================

因為我將工作排程的設定寫在DB裡,所以要修改時間我是另外寫在DAO裡面去修改,先sched.deleteJob(JobKey) 然後在修改DB時間,在呼叫sched.scheduleJob來啟動。

也因為這樣讓程式可以活一點,開關排程以及修改排程時間都可以不用在重新編譯及打包。
Quartz Scheduler就介紹到這,感謝收看的各位大大,有其他建議歡迎提出來一起討論哦^^

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 小山 的頭像
    小山

    小山的JAVA世界

    小山 發表在 痞客邦 留言(0) 人氣()