posts - 40,  comments - 187,  trackbacks - 0

书接上回,上回说到,我们已经将页面的时间设置转为了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

posted on 2007-01-10 16:55 小立飞刀 阅读(20654) 评论(22)  编辑  收藏 所属分类: Spring

FeedBack:
# re: Spring Quartz如何动态配置时间(3)
2007-01-10 17:14 | zip
good!  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-01-10 17:55 | ajax java group
感觉有点像 crontab .....  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-01-11 10:19 | 小雪飞刀
其实Quartz的Cron Expression就是来自Unix中,所以感觉很像crontab命令  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-01-11 18:25 | yy77
上面这个updateNotificationInterval究竟写在哪个类里面呢?这个类要在xml里面怎么配置才能够得到scheduler的对象呢?
看最后声明的那部分没有这个类的部分啊。难道是直接通过context来获得么?  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-01-15 10:59 | 小雪飞刀
to yy77

updateNotificationInterval() 这个方法可以写在你的业务逻辑类中,scheduler对象在这个类中注入就可以用了。如:
public class SchedulerService {

private Scheduler scheduler;

/**
* @param scheduler The scheduler to set.
*/
public void setScheduler(Scheduler scheduler) {
this.scheduler = scheduler;
}

public void updateNotificationInterval(...) {
//...
scheduler.rescheduleJob(...);
//...
}
}
在Spring中的配置如下:
<bean id="schedulerServiceTarget" class="SchedulerService">
<property name="scheduler" ref="schedulerFactory" />
</bean>
而schedulerFactory这个bean我在文章中写到了
< bean id ="schedulerFactory"
class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
< property name ="triggers" >
< list >
< ref local ="compareTrigger" />
</ list >
</ property >
</ bean >

不知道这样能不能回答你的问题呢,yy77 ?;-)

  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)[未登录]
2007-02-12 16:48 | Spring
我想请问一下:我都配置好了,程序到了制定的时间会进入方法A,我想在进入方法A后,就取得< value > 0 39 16 20 * ? </ value >这个值,应该怎么实现呢?谢谢
  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-02-12 17:00 | 小雪飞刀
@Spring
我理解您的意思是:
您的Method A中需要用到这个时间,但是不知道从哪里取到。

我的解决方法是将所有的时间规则放入数据库中,然后从数据库中读取最近插入的一个值就是所需时间了。

不知道这样能不能回答你的问题。  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)[未登录]
2007-02-13 09:36 | Spring
感谢您的回答,可能我没表达清楚我的意思!我现在的时间是在数据库中,就用您的方法假设,我要定时触发这个方法< property name ="targetMethod" value ="compare" /> ,但是这个方法会在不同的时间点多次触发,比如每月最后1天,每个星期第一天都是触发这个方法!我这里可以配置多个时间么?< property name ="cronExpression" >
< value > 0 39 16 20 * ? </ value >
</ property > 然后把这个时间值放进数据库查询!谢谢
  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)[未登录]
2007-02-13 15:16 | 过客
如果找不到调用的方法一般是什么错误?类的名字,方法名在多次查证都是正确的  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-02-13 15:32 | 小雪飞刀
@过客
能否把你的配置文件贴出来看看?  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-02-13 15:34 | 小雪飞刀
@Spring
我查阅了Quartz的文档,没有找到可以为一个Job配置多个value elements的方法,所以有个比较笨的方法是设置多个Job,让它们指向同一个Method,按照不同的时间执行。
  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-05-22 16:14 | jinhaha
请问我要是调用多个方法怎么办?  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-05-22 17:29 | 小雪飞刀
@jinhaha

理论上时可以的。你可以通过加载mutiple propertys达到调用多个方法的目的。如:
<property name="targetMethod">
<list>
<value>register</value>
<value>compare</value>
</list>
</property>

不过我没有实际实验过,您可以实验一下,告诉我结果 :)
  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-08-10 12:14 | boddi
thrank you!
  是这样的,客户有个需求是可以自己修改任务的间隔时间的!(这个值是设置到数据库中的),因为SimpleTriggerBean必须设置repeatInterval属性,而这个值因为是保存在数据中的,所以我想设置两个定时任务CMSTransformCRMTrigger和ScheduleInfoActionTrigger,ScheduleInfoActionTrigger在CMSTransformCRMTrigger任务执行前触发:其目的是为CMSTransformCRMTrigger根据数据库的值设置其repeatInterval属性,配置文件如下:
    <bean id="CMSTransformCRMEngine" class="org.springframework.aop.framework.ProxyFactoryBean">
        
<property name="targetSource">
            
<bean class="org.springframework.aop.target.SingletonTargetSource">
                
<constructor-arg>
                    
<bean class="com.server.business.cms.CMSTransformCRMEngine"/>
                
</constructor-arg>
            
</bean>
        
</property>
        
<property name="interceptorNames">
            
<list>
                
<value>CallContextInterceptor</value>
            
</list>
        
</property>
    
</bean>

 
<bean id="CMSTransformCRMJob" class="org.springframework.scheduling.quartz.JobDetailBean">         
        
<property name="jobClass">
            
<value>com.wisecrm.server.business.cms.CMSTransformCRMScheduledTask</value>
        
</property>    
        
<property name="jobDataAsMap">
            
<map>
                
<entry key="cmsTranCRMEnginer">
                    
<ref bean="CMSTransformCRMEngine"></ref>
                
</entry>
            
</map>
        
</property>
    
</bean>
    
     
<bean id="CMSTransformCRMTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">         
        
<property name="jobDetail">
            
<ref bean="CMSTransformCRMJob"></ref>
        
</property>    
        
<property name="startDelay">
            
<value>90000</value>
        
</property>
        
<property name="repeatInterval">
            
<value>90000</value>
        
</property>
    
</bean>
    
    
<bean id="ScheduleInfoAction" class="com.wisecrm.server.business.cms.ScheduleInfoAction">         
        
<property name="dataSource" ref="DataSource"/>     
        
<property name="scheduler" ref="schedulerFactory"/>     
    
</bean>
    
    
<bean id="ScheduleInfoActionFactory" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        
<property name="targetObject" ref="ScheduleInfoAction"/>
        
<property name="targetMethod">
             
<value>setTaskTimeByPreference</value>
        
</property>
        
<!--property name="arguments">
            <list>
                <ref local="DataSource"/>
                <ref local="schedulerFactory"/>
            </list>
        </property
-->
        
<property name="concurrent" value="false"/>
    
</bean>
    
    
<bean id="ScheduleInfoActionTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">         
        
<property name="jobDetail">
            
<ref bean="ScheduleInfoActionFactory"></ref>
        
</property>    
        
<property name="startDelay">
            
<value>80000</value>
        
</property>
        
<property name="repeatInterval">
            
<value>50000</value>
        
</property>
    
</bean>
    
    
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">         
        
<property name="triggers">             
            
<list>                 
                
<ref local="CMSTransformCRMTrigger"/>             
                
<ref local="ScheduleInfoActionTrigger"/>             
            
</list>         
        
</property>
    
</bean>

ScheduleInfoAction是动态设置间隔时间的接口:
public class ScheduleInfoAction {

    
private Scheduler scheduler;

    
public void setTaskTimeByPreference() throws SchedulerException {
        
if (isStartCMSTransformCRMTask()) {
            SimpleTriggerBean trigger 
= (SimpleTriggerBean) scheduler.getTrigger("ScheduleInfoActionTrigger",
                            Scheduler.DEFAULT_GROUP);
            trigger.setRepeatInterval(Long.parseLong(Application.getSystemSettingService().getPrefValue(
"CMSPeriod")));
            scheduler.rescheduleJob(
"ScheduleInfoActionTrigger",
                    Scheduler.DEFAULT_GROUP, trigger);
        }
 
else {
            scheduler.shutdown();
        }

    }


    public
 boolean isStartCMSTransformCRMTask() {
        
return Application.getSystemSettingService().getPrefValue("CMSPeriod"!= null;
    }


    public
 Scheduler getScheduler() {
        
return scheduler;
    }


    public
 void setScheduler(Scheduler scheduler) {
        
this.scheduler = scheduler;
    }


}
  但是不知为和两个任务都不执行?
后面我再在程序启动时就通过ScheduleInfoAction的factoryBean
设置CMSTransformCRMTrigger其repeatInterval属性,只保留一个定时任务就可以了,
配置如下:
<bean id="ScheduleInfoAction" class="com.wisecrm.server.business.cms.ScheduleInfoAction">         
        
<property name="scheduler" ref="schedulerFactory"/>     
    
</bean>
    
    
<bean id="ScheduleInfoActionFactory" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        
<property name="targetObject" ref="CMSTransformCRMEngine"/>
        
<property name="targetMethod">
             
<value>run</value>
        
</property>
        
<property name="concurrent" value="false"/>
    
</bean>
    
    
<bean id="ScheduleInfoActionTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">         
        
<property name="jobDetail">
            
<ref bean="ScheduleInfoActionFactory"></ref>
        
</property>    
        
<property name="startDelay">
            
<value>80000</value>
        
</property>
        
<property name="repeatInterval">
            
<value>80000</value>
        
</property>
    
</bean>
    
    
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">         
        
<property name="triggers">             
            
<list>            
                
<ref bean="ScheduleInfoActionTrigger"/>             
            
</list>         
        
</property>
    
</bean>
但总感觉到有点笨拙,你帮忙参考下   回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-08-10 14:32 | 小雪飞刀
@boddi
首先Scheduler是接口不是类,其次FactoryBean that sets up a Quartz Scheduler, manages its lifecycle as part of the Spring application context, and exposes the Scheduler reference for dependency injection.

您下面这个配置我不太明白是什么意思?能否把整个配置文件贴出来?
  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-08-11 14:56 | boddi

thrank you!
  是这样的,客户有个需求是可以自己修改任务的间隔时间的!(这个值是设置到数据库中的),因为SimpleTriggerBean必须设置repeatInterval属性,而这个值因为是保存在数据中的,所以我想设置两个定时任务CMSTransformCRMTrigger和ScheduleInfoActionTrigger,ScheduleInfoActionTrigger在CMSTransformCRMTrigger任务执行前触发:其目的是为CMSTransformCRMTrigger根据数据库的值设置其repeatInterval属性,配置文件如下:

    <bean id="CMSTransformCRMEngine" class="org.springframework.aop.framework.ProxyFactoryBean">
        
<property name="targetSource">
            
<bean class="org.springframework.aop.target.SingletonTargetSource">
                
<constructor-arg>
                    
<bean class="com.server.business.cms.CMSTransformCRMEngine"/>
                
</constructor-arg>
            
</bean>
        
</property>
        
<property name="interceptorNames">
            
<list>
                
<value>CallContextInterceptor</value>
            
</list>
        
</property>
    
</bean>

 
<bean id="CMSTransformCRMJob" class="org.springframework.scheduling.quartz.JobDetailBean">         
        
<property name="jobClass">
            
<value>com.wisecrm.server.business.cms.CMSTransformCRMScheduledTask</value>
        
</property>    
        
<property name="jobDataAsMap">
            
<map>
                
<entry key="cmsTranCRMEnginer">
                    
<ref bean="CMSTransformCRMEngine"></ref>
                
</entry>
            
</map>
        
</property>
    
</bean>
    
     
<bean id="CMSTransformCRMTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">         
        
<property name="jobDetail">
            
<ref bean="CMSTransformCRMJob"></ref>
        
</property>    
        
<property name="startDelay">
            
<value>90000</value>
        
</property>
        
<property name="repeatInterval">
            
<value>90000</value>
        
</property>
    
</bean>
    
    
<bean id="ScheduleInfoAction" class="com.wisecrm.server.business.cms.ScheduleInfoAction">         
        
<property name="dataSource" ref="DataSource"/>     
        
<property name="scheduler" ref="schedulerFactory"/>     
    
</bean>
    
    
<bean id="ScheduleInfoActionFactory" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        
<property name="targetObject" ref="ScheduleInfoAction"/>
        
<property name="targetMethod">
             
<value>setTaskTimeByPreference</value>
        
</property>
        
<!--property name="arguments">
            <list>
                <ref local="DataSource"/>
                <ref local="schedulerFactory"/>
            </list>
        </property
-->
        
<property name="concurrent" value="false"/>
    
</bean>
    
    
<bean id="ScheduleInfoActionTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">         
        
<property name="jobDetail">
            
<ref bean="ScheduleInfoActionFactory"></ref>
        
</property>    
        
<property name="startDelay">
            
<value>80000</value>
        
</property>
        
<property name="repeatInterval">
            
<value>50000</value>
        
</property>
    
</bean>
    
    
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">         
        
<property name="triggers">             
            
<list>                 
                
<ref local="CMSTransformCRMTrigger"/>             
                
<ref local="ScheduleInfoActionTrigger"/>             
            
</list>         
        
</property>
    
</bean>


ScheduleInfoAction是动态设置间隔时间的接口:

public class ScheduleInfoAction {

    
private Scheduler scheduler;

    
public void setTaskTimeByPreference() throws SchedulerException 
{
        
if (isStartCMSTransformCRMTask()) 
{
            SimpleTriggerBean trigger 
= (SimpleTriggerBean) scheduler.getTrigger("ScheduleInfoActionTrigger
",
                            Scheduler.DEFAULT_GROUP);
            trigger.setRepeatInterval(Long.parseLong(Application.getSystemSettingService().getPrefValue(
"CMSPeriod
")));
            scheduler.rescheduleJob(
"ScheduleInfoActionTrigger
",
                    Scheduler.DEFAULT_GROUP, trigger);
        }
 
else {
            scheduler.shutdown();
        }

    }


    public
 boolean isStartCMSTransformCRMTask() {
        
return Application.getSystemSettingService().getPrefValue("CMSPeriod"!= null
;
    }


    public
 Scheduler getScheduler() {
        
return scheduler;
    }


    public
 void setScheduler(Scheduler scheduler) {
        
this.scheduler 
= scheduler;
    }


}

  但是不知为和两个任务都不执行?

后面我再在程序启动时就通过ScheduleInfoAction的factoryBean

设置CMSTransformCRMTrigger其repeatInterval属性,只保留一个定时任务就可以了,

配置如下:


<bean id="ScheduleInfoAction" class="com.wisecrm.server.business.cms.ScheduleInfoAction">         
        
<property name="scheduler" ref="schedulerFactory"/>     
    
</bean>
    
    
<bean id="ScheduleInfoActionFactory" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        
<property name="targetObject" ref="CMSTransformCRMEngine"/>
        
<property name="targetMethod">
             
<value>run</value>
        
</property>
        
<property name="concurrent" value="false"/>
    
</bean>
    
    
<bean id="ScheduleInfoActionTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">         
        
<property name="jobDetail">
            
<ref bean="ScheduleInfoActionFactory"></ref>
        
</property>    
        
<property name="startDelay">
            
<value>80000</value>
        
</property>
        
<property name="repeatInterval">
            
<value>80000</value>
        
</property>
    
</bean>
    
    
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">         
        
<property name="triggers">             
            
<list>            
                
<ref bean="ScheduleInfoActionTrigger"/>             
            
</list>         
        
</property>
    
</bean>


但总感觉到有点笨拙,你帮忙参考下,为什么repeatInterval不能通过继承SimpleTriggerBean复写getRepeatInterval方法去设置呢?

  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2007-08-22 11:36 | kk
问一下:
Qest1:rescheduleJob是不是在两种场景下使用,一是服务重启时,一是用户需要更改任务的时间规则(触发器)时?

Qest2:用户在更改任务的时间规则(触发器)时,可能还需要任务已经运行的状态信息。
场景一:某个任务从2007/1/1日开始,每天8:30运行。到了2007/5/1日,用户想更改为每天9:00运行,新触发器设为2007/1/1,9:00。希望的更新触发器后第一次运行时间是2007/5/2日 9:00。请问quartz可以做到吗?
场景二:某任务的执行次数为100次,当执行到30次时,用户希望把执行次数改为150次,新触发器设为150次,所以任务还需执行150-(100-30)=80次。请问quartz可以做到吗?  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2008-10-28 15:28 | 风续飘
你好,我是刚刚搞开发不久,想学习quartz,你的这个程序的时间是从数据库里来读取的吗?能不能把你的表结构发我看看,感激不尽!  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2008-10-30 13:17 | 小立飞刀
@风续飘

表结构很简单,只需要key,value两个字段就可以满足要求。您也可以采用其他存储方式,如存入xml中。  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2009-04-23 18:18 | sunday
@kk
你好,我也碰到了你所说的第一种情况,不知您是怎么解决的?  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)
2009-04-28 13:33 | 小立飞刀
@sunday
什么情况 能否说得详细些?
  回复  更多评论
  
# re: Spring Quartz如何动态配置时间(3)[未登录]
2009-07-27 16:37 | jim
这位大哥,请问你的问题解决了吗,我现在遇到同样的需求,请问如何实现  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2008年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

生存或毁灭,这是个必答之问题:是否应默默的忍受坎苛命运之无情打击,还是应与深如大海之无涯苦难奋然为敌,并将其克服。此二抉择,究竟是哪个较崇高?

常用链接

留言簿(12)

随笔分类(43)

相册

收藏夹(7)

朋友的博客

电子资料

搜索

  •  

积分与排名

  • 积分 - 301509
  • 排名 - 192

最新评论

阅读排行榜

评论排行榜