什麼是動态定時任務:是由客戶制定生成的,服務端隻知道該去執行什麼任務,但任務的定時是不确定的(是由客戶制定)。
這樣總不能修改配置檔案每定制個定時任務就增加一個trigger吧,即便允許客戶修改配置檔案,但總需要重新啟動web服務啊,研究了下quartz在spring中的動态定時,發現
0/10 ?
中cronexpression是關鍵,如果可以動态設定cronexpression的值,也就說如果我們可以直接調用crontriggerbean中設定cronexpression的方法,就可以順利解決問題了。
熟悉1的朋友可以跳過不看,下面2、3是動态定時任務的具體實作。
<a></a>
1. quartz在spring中的簡單配置
spring配置檔案:
targetmethod" value="simplejobtest"/>
cronexpression**">
在上面的配置中設定了
① targetmethod: 指定需要定時執行scheduleinfoaction中的simplejobtest()方法
② concurrent:對于相同的jobdetail,當指定多個trigger時, 很可能第一個job完成之前,第二個job就開始了。指定concurrent設為false,多個job不會并發運作,第二個job将不會在第一個job完成之前開始。
③ cronexpression:0/10 ?表示每10秒執行一次,具體可參考附表。
④ triggers:通過再添加其他的ref元素可在list中放置多個觸發器。
scheduleinfoaction中的simplejobtest()方法
注意:此方法沒有參數,如果scheduleinfoaction有兩個方法simplejobtest()和simplejobtest(string argument),則spring隻會去執行無參的simplejobtest().
public void simplejobtest() {
log.warn(“uh oh, job is scheduled !’” + “‘ success…”);
}
2.quartz在spring中動态設定crontrigger方法一
scheduler**" ref="schedulerfactory"/>
scheduleinfomanager**" ref="scheduleinfomanager"/>
reschedulejob**"/>
crontrigger**" class="org.springframework.scheduling.quartz.crontriggerbean" >
scheduleinfoaction中的reschedulejob ()方法及相關方法
① reschedulejob讀取資料庫,獲得自定義定時器排程時間():
private void reschedulejob() throws schedulerexception, parseexception {
// 運作時可通過動态注入的scheduler得到trigger
crontriggerbean trigger = (crontriggerbean) scheduler.gettrigger(
“crontrigger“, scheduler.default_group);
string dbcronexpression = getcronexpressionfromdb();
string originconexpression = trigger.getcronexpression();
// 判斷從db中取得的任務時間(dbcronexpression)和現在的quartz線程中的任務時間(originconexpression)是否相等
// 如果相等,則表示使用者并沒有重新設定資料庫中的任務時間,這種情況不需要重新reschedulejob
if(!originconexpression.equalsignorecase(dbcronexpression)){
trigger.setcronexpression(dbcronexpression);
scheduler.reschedulejob(“crontrigger“, scheduler.default_group, trigger);
}
// 下面是具體的job内容,可自行設定
// executejobdetail();
}
② getcronexpressionfromdb():從資料庫中獲得dbcronexpression的具體代碼,由于使用了scheduleinfomanager,是以要在定義相應的setter方法
private string getcronexpressionfromdb(){
string sql=”from scheduleinfo scheduleinfo where 1=1 “;
sql=sql+” and scheduleinfo.infoid = ‘“+”1” + “‘“;
list schedulelist = scheduleinfomanager.queryscheduleinlistbysql(sql);
scheduleinfo scheduleinfo = (scheduleinfo)schedulelist.get(0);
string dbcronexpression = scheduleinfo.getcronexpression();
return dbcronexpression;
③ 在spring配置檔案的scheduleinfoaction配置了相應的property(scheduler/ scheduleinfomanager),要為其設定setter方法
private scheduler scheduler;
// 設值注入,通過setter方法傳入被調用者的執行個體scheduler
public void setscheduler(scheduler scheduler) {
this.scheduler = scheduler;
}
private scheduleinfomanager scheduleinfomanager;
// 設值注入,通過setter方法傳入被調用者的執行個體scheduleinfomanager
public void setscheduleinfomanager(scheduleinfomanager scheduleinfomanager){
this.scheduleinfomanager = scheduleinfomanager;
3. quartz在spring中動态設定crontrigger方法二
在上面的2中我們可以看到,盡管已經可以動态進行reschedulejob了,不過依然需要我們設定一個cronexpression,如果嘗試一下拿掉spring配置中的
cronexpression**">
則容器(如tomcat)啟動時會報錯。
實際中我們希望tomcat啟動時就可以直接去讀資料庫,拿到相應的dbcronexpression,然後定時執行一個job,而不希望配置初始的cronexpression ,觀察下面的crontriggerbean,考慮到cronexpression需要初始化,如果設定一個類initializingcrontrigger繼承crontriggerbean,然後在這個類中做一些讀取db的初始化工作(設定cronexpression),問題就可以解決了。
crontrigger**" class="com.lively.happyoa.jobs.webapp.action.scheduleinfoaction.**initializingcrontrigger**">
scheduleinfomanager**" ref="scheduleinfomanager"/>
initializingcrontrigger中的相關方法
注意:在注入scheduleinfomanager屬性的時候,我們可以去讀取db任務時間(之是以放在setter方法中,是因為需要在設定scheduleinfomanager後進行getcronexpressionfromdb(),否則,也可以①②邏輯把放在類的構造函數中).
注意initializingcrontrigger必須extends crontriggerbean.
public class initializingcrontrigger extends crontriggerbean implements serializable {
// 因為在getcronexpressionfromdb使用到了scheduleinfomanager,是以
// 必須上一行代碼設定scheduleinfomanager後進行getcronexpressionfromdb
string cronexpression = getcronexpressionfromdb (); // ①
// 因為extends crontriggerbean ,此處調用父類方法初始化cronexpression
setcronexpression(cronexpression); // ②
……
附表:
“0 0 12 ?” 每天中午12點觸發
“0 15 10 ? “ 每天上午10:15觸發
“0 15 10 ?” 每天上午10:15觸發
“0 15 10 ? “ 每天上午10:15觸發
“0 15 10 ? 2005” 2005年的每天上午10:15觸發
“0 14 ?” 在每天下午2點到下午2:59期間的每1分鐘觸發
“0 0/5 14 ?” 在每天下午2點到下午2:55期間的每5分鐘觸發
“0 0/5 14,18 ?” 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發
“0 0-5 14 ?” 在每天下午2點到下午2:05期間的每1分鐘觸發
“0 10,44 14 ? 3 wed” 每年三月的星期三的下午2:10和2:44觸發
“0 15 10 ? mon-fri” 周一至周五的上午10:15觸發
“0 15 10 15 ?” 每月15日上午10:15觸發
“0 15 10 l ?” 每月最後一日的上午10:15觸發
“0 15 10 ? 6l” 每月的最後一個星期五上午10:15觸發
“0 15 10 ? 6l 2002-2005” 2002年至2005年的每月的最後一個星期五上午10:15觸發
“0 15 10 ? 6#3” 每月的第三個星期五上午10:15觸發
至于每個符号 看看例子就好了.很簡單了.