Spring Quartz如何動態配置時間

1. 目的:動態設置時間,觸發相應的任務

2. 系統架構爲 struts + spring + hibernate

3. 實現步驟:
  • 在頁面上設置時間;
  • 將時間轉換爲Unix Cron Expression;
  • 將轉換後的時間規則表達式記錄到數據庫中(也能夠寫入xml文件中,這裏是項目須要記錄入數據庫中);
  • 從數據庫中獲得相應的時間規則表達式;
  • 更新您的任務觸發器的時間設置;
  • RESCHEDULE THE JOB。; - )
4. 具體實現細節:
1) 在頁面上設置時間
根據具體的業務需求,設置時間規則,下面以某一項目爲例,須要 按每個月、每週、自定義分爲三種規則。
 1 < tr >
 2            < th > 執行這個任務 </ th >
 3            < td  style ="font-weight:bold;" >
 4             < html:radio  property ="everyWhat"  styleClass ="InputBorderNone"  value ="monthly"  onclick ="changeStatus(this.value)" > 每個月 </ html:radio >
 5             < html:radio  property ="everyWhat"  styleClass ="InputBorderNone"  value ="weekly"  onclick ="changeStatus(this.value)" > 每週 </ html:radio >
 6             < html:radio  property ="everyWhat"  styleClass ="InputBorderNone"  value ="userDefined"  onclick ="changeStatus(this.value)" > 自定義 </ html:radio >
 7             < html:hidden  property ="jobName"  value ="compare"   />
 8            </ td >
 9 </ tr >
10

每個月則須要選擇該月的第幾個星期的星期幾
 1 < tr  style ="display:"  id ="whichWeek" >
 2            < th > 選擇第幾個星期 </ th >
 3            < td  style ="font-weight:bold;" >
 4             < html:select  property ="week" >
 5              < html:option  value ="1" > </ html:option >
 6              < html:option  value ="2" > </ html:option >
 7              < html:option  value ="3" > </ html:option >
 8              < html:option  value ="4" > </ html:option >
 9             </ html:select >
10             < html:select  property ="dayOfMonth" >
11              < html:option  value ="1" > 星期日 </ html:option >
12              < html:option  value ="2" > 星期一 </ html:option >
13              < html:option  value ="3" > 星期二 </ html:option >
14              < html:option  value ="4" > 星期三 </ html:option >
15              < html:option  value ="5" > 星期四 </ html:option >
16              < html:option  value ="6" > 星期五 </ html:option >
17              < html:option  value ="7" > 星期六 </ html:option >
18             </ html:select >
19           </ td >  
20   </ tr >
21

每週則須要選擇星期幾
 1 < tr  style ="display:none"  id ="whichDay" >
 2            < th > 選擇星期 </ th >
 3            < td  style ="font-weight:bold;" >
 4             < html:select  property ="dayOfWeek" >
 5              < html:option  value ="1" > 星期日 </ html:option >
 6              < html:option  value ="2" > 星期一 </ html:option >
 7              < html:option  value ="3" > 星期二 </ html:option >
 8              < html:option  value ="4" > 星期三 </ html:option >
 9              < html:option  value ="5" > 星期四 </ html:option >
10              < html:option  value ="6" > 星期五 </ html:option >
11              < html:option  value ="7" > 星期六 </ html:option >
12             </ html:select >
13          </ td >  
14    </ tr >
15

自定義則選擇具體的日期,如 2007-1-10

三種規則都須要設定時間點
 1 < tr >
 2            < th > 起始時間 </ th >
 3            < td  style ="font-weight:bold;" >
 4             < html:select  property ="timeType"  styleId ="type"  onchange ="changeStatus2(this.value)" >
 5              < html:option  value ="AM" > 上午 </ html:option >
 6              < html:option  value ="PM" > 下午 </ html:option >
 7             </ html:select >
 8             < html:select  property ="hour"  styleId ="amHours" >
 9              < html:option  value ="1" > 1 </ html:option >
10              < html:option  value ="2" > 2 </ html:option >
11              < html:option  value ="3" > 3 </ html:option >
12              < html:option  value ="4" > 4 </ html:option >
13              < html:option  value ="5" > 5 </ html:option >
14              < html:option  value ="6" > 6 </ html:option >
15              < html:option  value ="7" > 7 </ html:option >
16              < html:option  value ="8" > 8 </ html:option >
17              < html:option  value ="9" > 9 </ html:option >
18              < html:option  value ="10" > 10 </ html:option >
19              < html:option  value ="11" > 11 </ html:option >
20              < html:option  value ="12" > 12 </ html:option >
21             </ html:select >
22             < html:select  property ="hour"  styleId ="pmHours"  style ="display:none" >
23              < html:option  value ="13" > 13 </ html:option >
24              < html:option  value ="14" > 14 </ html:option >
25              < html:option  value ="15" > 15 </ html:option >
26              < html:option  value ="16" > 16 </ html:option >
27              < html:option  value ="17" > 17 </ html:option >
28              < html:option  value ="18" > 18 </ html:option >
29              < html:option  value ="19" > 19 </ html:option >
30              < html:option  value ="20" > 20 </ html:option >
31              < html:option  value ="21" > 21 </ html:option >
32              < html:option  value ="22" > 22 </ html:option >
33              < html:option  value ="23" > 23 </ html:option >
34              < html:option  value ="0" > 0 </ html:option >
35             </ html:select >  點
36              < html:text  property ="minute"  name ="minute"  style ="width:20px;"  value ="0"  onchange ="valTime(this.value)"   />  分
37              < html:text  property ="second"  name ="second"  style ="width:20px;"  value ="0"  onchange ="valTime(this.value)"   />  秒(0-59之間的整數)
38        </ td >  
39 </ tr >
40

OK. 這樣咱們的頁面設置就完成了。: - ) 
上回說到,咱們的設置頁面已經作好了,接下來就是將時間轉換爲Unix Cron Expression。

2) 將時間轉換爲Unix Cron Expression

須要ActionForm將頁面表單數據映射到Action中,而後在Action中轉換爲cron expression:

 1 SchedulerForm schedulerForm  =  (SchedulerForm) form;
 2         String jobName  =  schedulerForm.getJobName();
 3         String cronExpression  =   "" ;
 4         String[] commonNeeds  =   {schedulerForm.getSecond(), schedulerForm.getMinute(), schedulerForm.getHour()} ;
 5         String[] monthlyNeeds  =   {schedulerForm.getWeek(), schedulerForm.getDayOfMonth()} ;
 6         String weeklyNeeds  =  schedulerForm.getDayOfWeek();
 7         String userDefinedNeeds  =  schedulerForm.getDate();
 8         String everyWhat  =  schedulerForm.getEveryWhat();
 9          // 獲得時間規則
10         cronExpression  =  CronExpConversion.getCronExpression(everyWhat, commonNeeds,
11                 monthlyNeeds, weeklyNeeds, userDefinedNeeds);
12

我定義了一個 規則類來處理轉換規則(寫得不是很好 能用就行 嘿嘿)
 1
 2 /**
 3  * 頁面設置轉爲UNIX cron expressions 轉換類
 4  * CronExpConversion
 5   */

 6 public   class  CronExpConversion  {
 7     
 8      /**
 9      * 頁面設置轉爲UNIX cron expressions 轉換算法
10      *  @param  everyWhat
11      *  @param  commonNeeds 包括 second minute hour
12      *  @param  monthlyNeeds 包括 第幾個星期 星期幾
13      *  @param  weeklyNeeds  包括 星期幾
14      *  @param  userDefinedNeeds  包括具體時間點
15      *  @return  cron expression
16       */

17      public   static  String convertDateToCronExp(String everyWhat,
18             String[] commonNeeds, String[] monthlyNeeds, String weeklyNeeds,
19             String userDefinedNeeds)  {
20         String cronEx  =   "" ;
21         String commons  =  commonNeeds[ 0 +   "   "   +  commonNeeds[ 1 +   "   "
22                  +  commonNeeds[ 2 +   "   " ;
23         String dayOfWeek  =   "" ;
24          if  ( " monthly " .equals(everyWhat))  {
25              //  eg.: 6#3 (day 6 = Friday and "#3" = the 3rd one in the
26              //  month)
27             dayOfWeek  =  monthlyNeeds[ 1 ]
28                      +  CronExRelated.specialCharacters
29                             .get(CronExRelated._THENTH)  +  monthlyNeeds[ 0 ];
30             cronEx  =  (commons
31                      +  CronExRelated.specialCharacters.get(CronExRelated._ANY)
32                      +   "   "
33                      +  CronExRelated.specialCharacters.get(CronExRelated._EVERY)
34                      +   "   "   +  dayOfWeek  +   "   " ).trim();
35         }
  else   if  ( " weekly " .equals(everyWhat))  {
36             dayOfWeek  =  weeklyNeeds;  //  1
37             cronEx  =  (commons
38                      +  CronExRelated.specialCharacters.get(CronExRelated._ANY)
39                      +   "   "
40                      +  CronExRelated.specialCharacters.get(CronExRelated._EVERY)
41                      +   "   "   +  dayOfWeek  +   "   " ).trim();
42         }
  else   if  ( " userDefined " .equals(everyWhat))  {
43             String dayOfMonth  =  userDefinedNeeds.split( " - " )[ 2 ];
44              if  (dayOfMonth.startsWith( " 0 " ))  {
45                 dayOfMonth  =  dayOfMonth.replaceFirst( " 0 " "" );
46             }

47             String month  =  userDefinedNeeds.split( " - " )[ 1 ];
48              if  (month.startsWith( " 0 " ))  {
49                 month  =  month.replaceFirst( " 0 " "" );
50             }

51             String year  =  userDefinedNeeds.split( " - " )[ 0 ];
52              // FIXME 暫時不加年份 Quartz報錯
53              /* cronEx = (commons + dayOfMonth + " " + month + " "
54                     + CronExRelated.specialCharacters.get(CronExRelated._ANY)
55                     + " " + year).trim(); */

56             cronEx  =  (commons  +  dayOfMonth  +   "   "   +  month  +   "   "
57                      +  CronExRelated.specialCharacters.get(CronExRelated._ANY)
58                      +   "   " ).trim();
59         }

60          return  cronEx;
61     }
    
62 }

63
這樣就將頁面的時間設置轉爲了Cron Expression。
書接上回,上回說到,咱們已經將頁面的時間設置轉爲了Cron Expression,下面我記錄了時間規則。

3) 記錄時間規則

      我將時間規則存入數據庫中,目的是爲了生成歷史日誌,也能夠存入XML文件中。固然您也能夠省略此步,直接將轉換後的規則放入相應的Quartz trigger中。

4) 更新任務觸發器的時間設置

到了關鍵的一步了,也是最簡單的一步,一個方法就能夠實現了。
首先,咱們須要經過trigger的名稱獲得一個CronTriggerBean;
其次,經過trigger的setCronExpression(String cronExp)方法將新的表達式注入;
最後,RESCHEDULE THE JOB,OK!

 1     /**
 2      * 自定義定時器調度時間
 3      *  @param
 triggerName 觸發器名稱
 4       *  @throws
 Exception 
 5       */

 6      public   void  updateNotificationInterval(String triggerName, String triggerId)
 7              throws  SchedulerException, ParseException 
{
 8          // 獲得trigger

 9         CronTriggerBean trigger  =  (CronTriggerBean) scheduler.getTrigger(
10
                triggerName, Scheduler.DEFAULT_GROUP);
11          // 獲得cron expression        

12         String cronExpression  =  schedulerDAO.getCronExpression(triggerId);
13          // 設置trigger的時間規則

14         trigger.setCronExpression(cronExpression);
15          // 重置job

16         scheduler.rescheduleJob(triggerName, Scheduler.DEFAULT_GROUP, trigger);
17     }

18
至此,目的達到了,快樂的看着您的任務在您自定義的時間下快樂的執行,您是否也想像'Happy Feet'中那隻快樂的企鵝同樣,Show段踢踏呢 ; - D




PS:忘了說個人Quartz任務是怎麼配置的了,罪過,罪過。

< bean  id ="compareJob"
        class
="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
        
< property  name ="targetObject"  ref ="compareService"   />
        
< property  name ="targetMethod"  value ="compare"   />
        
< property  name ="concurrent"  value ="false"   />
    
</ bean >  

    
< bean  id ="compareTrigger"

        class
="org.springframework.scheduling.quartz.CronTriggerBean" >
        
< property  name ="jobDetail"  ref ="compareJob"   />
        
< property  name ="cronExpression" >             
            
< value > 0 39 16 20 * ? </ value >
        
</ property >
    
</ bean >

< bean  id ="schedulerFactory"
        class
="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
        
< property  name ="triggers" >
            
< list >                     
                     < ref  local ="compareTrigger"   />

            
</ list >
        
</ property >
    
</ bean >


                                                                                     THE END
相關文章
相關標籤/搜索