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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值