天天看點

Quartz在Spring中動态設定cronExpression (spring設定動态定時任務)------轉帖

什麼是動态定時任務:是由客戶制定生成的,服務端隻知道該去執行什麼任務,但任務的定時是不确定的(是由客戶制定)。

這樣總不能修改配置檔案每定制個定時任務就增加一個trigger吧,即便允許客戶修改配置檔案,但總需要重新啟動web服務啊,研究了下quartz在spring中的動态定時,發現

              0/10 ?

     中cronexpression是關鍵,如果可以動态設定cronexpression的值,也就說如果我們可以直接調用crontriggerbean中設定cronexpression的方法,就可以順利解決問題了。

熟悉1的朋友可以跳過不看,下面2、3是動态定時任務的具體實作。

<a></a>

1. quartz在spring中的簡單配置

spring配置檔案:

         targetmethod" value="simplejobtest"/&gt;

          cronexpression**"&gt;

在上面的配置中設定了

① 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"/&gt;

         scheduleinfomanager**" ref="scheduleinfomanager"/&gt;

         reschedulejob**"/&gt;

     crontrigger**" class="org.springframework.scheduling.quartz.crontriggerbean" &gt;

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**"&gt;

則容器(如tomcat)啟動時會報錯。

實際中我們希望tomcat啟動時就可以直接去讀資料庫,拿到相應的dbcronexpression,然後定時執行一個job,而不希望配置初始的cronexpression ,觀察下面的crontriggerbean,考慮到cronexpression需要初始化,如果設定一個類initializingcrontrigger繼承crontriggerbean,然後在這個類中做一些讀取db的初始化工作(設定cronexpression),問題就可以解決了。

    crontrigger**" class="com.lively.happyoa.jobs.webapp.action.scheduleinfoaction.**initializingcrontrigger**"&gt;

          scheduleinfomanager**" ref="scheduleinfomanager"/&gt;

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觸發

至于每個符号 看看例子就好了.很簡單了.