zoukankan      html  css  js  c++  java
  • 以代码的方式管理quartz定时任务的暂停、重启、删除、添加等

    【前言】在项目的管理功能中,对定时任务的管理有时会很常见。因为我们不能指望只在配置文件中配置好定时任务就行了,因为如果要控制定时任务的 “暂停” 呢?暂停之后又要在某个时间点 “重启” 该定时任务呢?或者说直接 “删除” 该定时任务呢?要改变某定时任务的触发时间呢? “添加” 一个定时任务对于系统的使用者而言,是不太现实的,因为一个定时任务的处理逻辑他是不可能完成的,还是必须得由开发人员去添加。一般来说,是针对 “已有” 定时任务进行的一些操作,这时候就必须要用到代码来操作了,因为此时通过配置来管控是不太现实的。

     

    版本:Spring4.x + quartz2.x

     

    首先,开发人员会在配置文件中配置一个定时任务(定时任务的实现略……)

     

    Java代码  收藏代码
    1. <bean id="job1" class="org.test.job.TestJob2" />     
    2.         
    3.     <!-- 定义触发器来管理任务bean -->    
    4.     <bean id="cronTriggerJob1"     
    5.         class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"    
    6.         p:cronExpression="0 52 17 * * ? *" >    
    7.         <property name="jobDetail">    
    8.             <bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean"    
    9.             p:durability="true"    
    10.             p:jobClass="org.test.job.TestJob1"    
    11.              />    
    12.         </property>    
    13.     </bean>    
    14.         
    15.     
    16.     </bean>    
    17.     <!-- 执行实际的调度 -->    
    18.     <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">    
    19.         <property name="triggers">    
    20.             <list>    
    21.                 <ref bean="cronTriggerJob1" />    
    22.             </list>    
    23.         </property>    
    24.     </bean>     

     

     

    我们怎么根据配置的bean来操作该定时任务的管理呢?

    需查阅spring4.x结合quartz2.x的底层API,并搞清楚以下概念:

    1)Trigger trigger. trigger.getKey()会得到两个东西——group:DEFAULT(默认的group name)、name(triggerName)。其中name对应的就是配置文件中配置的trigger的bean的id(或name)

    2)trigger.getJobKey()一样会得到两个东西——group:DEFAULT(默认的group name)、name(jobName)。其中jobName对应的就是配置文件中job的bean的id或name(本例为job1)

     

    注:以上粗体字的部分即为代码管理定时任务的关键之处!

     

    3)如何根据jobName查找到他关联到的trigger呢?

     

    quartz1.x还有这种语法,不过quartz2.x已经废除了:

    quartz1.x   Trigger trigger = sched.getTrigger(jobName,TRIGGER_GROUP_NAME);

     

    quartz2.x的相关语法(Scheduler类的方法)更为丰富,如下:

    public abstract List<? extends Trigger> getTriggersOfJob(JobKey paramJobKey)

     

        throws SchedulerException;

     

    public abstract List<String> getTriggerGroupNames()

        throws SchedulerException;

     

     public abstract Set<TriggerKey> getTriggerKeys(GroupMatcher<TriggerKey> paramGroupMatcher)

        throws SchedulerException;

     

     public abstract Trigger getTrigger(TriggerKey paramTriggerKey)

        throws SchedulerException;

     

    为了改变触发时间,

    Trigger trigger = TriggerBuilder.forJob(String jobName).newTrigger()..withSchedule(CronScheduleBuilder.cronSchedule(time))build();

    然后再用Scheduler调度类去执行:

    schedler.resumeTrigger(trigger.getKey());

    根据trigger得到相应的JobDetail:

    JobDetail jobDetail = (JobDetail) trigger.getJobDataMap().get("jobDetail");

     

    下面是对定时任务的管理(暂停、重启、删除):

     

     

    Java代码  收藏代码
    1. //暂停  
    2. //schduler.pauseTrigger(TriggerKey triggerKey)  
    3. scheduler.pauseJob(JobKey.jobKey("job1"));//停止触发器  
    4. Thread.sleep(1000*60*2);  
    5. //恢复    
    6. //scheduler.resumeJob(JobKey jobKey)则可恢复一个具体的job,  
    7. scheduler.resumeTrigger(TriggerKey.triggerKey("cronTriggerJob1"));  
    8. Thread.sleep(1000*60*2);  
    9. //删除  
    10. //没有deleteTrigger的方法  
    11. scheduler.deleteJob(JobKey.jobKey("job1"));  
    12. Thread.sleep(1000*60*2);  
    13. //删除后再次尝试重启(会失效)  
    14. scheduler.resumeTrigger(TriggerKey.triggerKey("cronTriggerJob1"));  

     代码经测试,有效,并注意到:

    当resume一个定时任务时,会立即执行该定时任务,执行完此次,然后再按原先设定的时间来定期执行

    当删除一个任务后,就算再次resume时,会失效,即并不会被恢复了。

     

    =========================================

    Spring bean必须注意的几点:

    1)bean的id和name是一回事儿;

    2)当一个bean类继承了InitializingBean接口后,必须实现其setBeanName(String name)抽象方法。name一般是bean的id或name属性值,此时bean实例化时方法的顺序为setProperties(String propName)->setBeanName()->afterPropertiesSet();

    3)当为了获得一个bean对外提供的接口方法时,必须先获得这个bean的bean对象,通过Spring的SpringContextHolder.getBean(beanId) (其中beanId为bean的id或name属性值)。而不能通过new或者getInstance(获取单例)的方式,否则获取不到该bean的其他属性值!

  • 相关阅读:
    android 线程的优先级设置方法
    android插件开发
    针对AsyncTask的分析
    针对平板的扩展
    adb shell dumpsys activity
    gzip相关【转帖】
    android中也需要SQL语句
    monkey脚本
    eclipse 引入外部包不能运行 NoClassDefFoundError 的问题
    翻译 : fragment
  • 原文地址:https://www.cnblogs.com/bevis-byf/p/10087032.html
Copyright © 2011-2022 走看看