Quartz动态改变Cron表达式,来实现动态执行Spring定时任务

时间:2022-06-10 21:35:36

Quartz定时器非常强大,但是有时候我们想要不重就能动态的改变Cron表达式的值。

这样我们可以在配置文件中(当然数据库也可以)配置一个表达式的值。

每次想改变表达式的值的时候手动修改配置文件中的表达式,实现动态表达式。

 

一:定时调度任务

public classDailyScheduledJobextendsQuartzJobBean {

   // 开关(控制定时任务是否开启)

   private Boolean isOpen;

   privateApplicationContextcontext;

   private staticLoggerlogger= Logger.getLogger(DailyScheduledJob.class);

 

   protected voidexecuteInternal(JobExecutionContextcontext)throwsJobExecutionException{

     //平台控制开关

      if (!isOpen) {

        return;

     }

      try {

        //清理过期订单

        cleanSubs();

     }catch (Exception e) {

        logger.error("Daily线程清理过期订单出错!",e);

     }

   }

 

   /**

    *清理过期订单

   */

  public voidcleanSubs() {

     try{

         ISubsService subsService =(ISubsService)context.getBean("subsService");

        subsService.cleanNoPayed();

     }catch (BeansException e) {

        logger.error("清理过期订单失败!");

     }catch (Exception ex) {

           logger.error("清理过期订单",ex);

       }

   }

  

   public void setContextUtil(ApplicationContextUtil contextUtil){

     this.context= contextUtil.getContext();

   }

  

   public void setIsOpen(Boolean isOpen) {

      this.isOpen= isOpen;

   }

}

 

二:spring配置

<beanid="dailyTask"

   class="org.springframework.scheduling.quartz.JobDetailFactoryBean">

   <propertyname="jobClass"value="com.google.busi.schedule.DailyScheduledJob"/>

   <propertyname="durability"value="true"/>

   <propertyname="jobDataMap">

      <map>

         <entrykey="contextUtil"value-ref="applicationContextUtil"/>

        <!--定时任务执行开关 -->

        <entrykey="isOpen"value="${googles.schedule.isopen}"/>

      </map>

   </property>

</bean>

<beanid="inquiryCronTrigger"class="com.google.busi.schedule.InitCronTriggerFactoryBean">

   <propertyname="jobDetail"ref="dailyTask"/>

   <!-- <property name="key"value="inquiryQuartzParam" /> -->

       <property name="baseConfigService"ref="baseConfigService"/>

</bean>

<beanid="schedulerFactoryBean"

   class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

   <propertyname="triggers">

      <list>

         <refbean="inquiryCronTrigger"/>

         <refbean="cronTrigger"/>

      </list>

   </property>

</bean>

 

三:项目启动时从数据库读取cron表达式,初始化Trigger

这里记得setName

/**

 *服务器启动时,从baseConfig读取配置文件配置的时间

 *@authorAdministrator

 *

 */

public classInitCronTriggerFactoryBeanextendsCronTriggerFactoryBeanimplementsSerializable {

  

   //private static final longserialVersionUID = 1L;

   private static final long serialVersionUID= -5937544121329980033L;

  

   public static finalStringSUBS_NOPAY_TRIGGER="SUBS_NOPAY_TRIGGER";

  

   privateIBaseConfigServicebaseConfigService;// =(IBaseConfigService)context.getBean("baseConfigService");

   /*private String key;

 

   public void setKey(String key) {

      this.key = key;

   }*/

 

   public void setBaseConfigService(IBaseConfigServicebaseConfigService) {

     this.baseConfigService=baseConfigService;

     setName(SUBS_NOPAY_TRIGGER);

     setCronExpression(getCronExpressionFromDB());

     System.out.println(SUBS_NOPAY_TRIGGER+":"+getCronExpressionFromDB());

   }

 

   private String getCronExpressionFromDB() {//从数据库拿到表达式

     StringsysParam =newString();

      returnDateUtil.parseExpression(Integer.valueOf(baseConfigService.loadBaseConfigByKey(Constants.NOPAY_SUBS_AGE).getConfigValue())/60);

   }

  

  

}

 

四:动态设置cron表达式的接口和实现类

接口

packagecom.google.busi.service.intf.busi;

 

importjava.util.Date;

 

importorg.quartz.CronExpression;

 

 

public interfaceISchedulerService {

    /**

     *根据Quartz Cron Expression调试任务

    *

     *@paramcronExpression

    *            Quartz Cron表达式,如"0/10 * * ? * * *"

    */

   voidschedule(String cronExpression);

 

    /**

     *根据Quartz Cron Expression调试任务

    *

     *@paramname

    *            Quartz CronTrigger名称

    *@param cronExpression

    *            Quartz Cron表达式,如"0/10 * * ? * * *"

    */

   voidschedule(String name,String cronExpression);

 

    /**

     *根据Quartz Cron Expression调试任务

    *

     *@paramname

    *            Quartz CronTrigger名称

    *@param group

    *            Quartz CronTrigger

     *@paramcronExpression

    *            Quartz Cron表达式,如"0/10 * * ? * * *"

    */

   voidschedule(String name,String group,String cronExpression);

 

    /**

     *根据Quartz Cron Expression调试任务

    *

     *@paramcronExpression

    *           Quartz CronExpression

     */

   voidschedule(CronExpression cronExpression);

 

    /**

     *根据Quartz Cron Expression调试任务

    *

     *@paramname

    *            Quartz CronTrigger名称

    *@param cronExpression

    *            Quartz CronExpression

     */

   voidschedule(String name,CronExpression cronExpression);

 

    /**

     *根据Quartz Cron Expression调试任务

    *

     *@paramname

    *            Quartz CronTrigger名称

    *@param group

    *            Quartz CronTrigger

    *@param cronExpression

    *            Quartz CronExpression

     */

   voidschedule(String name,String group,CronExpression cronExpression);

 

    /**

     *startTime时执行调试一次

    *

     *@paramstartTime

    *            调度开始时间

    */

   voidschedule(Date startTime);

 

    voidschedule(Date startTime,String group);

 

    /**

     *startTime时执行调试一次

    *

     *@paramname

    *            Quartz SimpleTrigger名称

    *@param startTime

    *           调度开始时间

     */

   voidschedule(String name,Date startTime);

 

    voidschedule(String name,Date startTime,String group);

 

    /**

     *startTime时执行调试,endTime结束执行调度

    *

     *@paramstartTime

    *           调度开始时间

    *@param endTime

    *            调度结束时间

    */

   voidschedule(Date startTime,Date endTime);

 

    voidschedule(Date startTime,Date endTime,String group);

 

    /**

     *startTime时执行调试,endTime结束执行调度

    *

     *@paramname

    *            Quartz SimpleTrigger名称

    *@param startTime

    *           调度开始时间

    *@param endTime

    *           调度结束时间

    */

   voidschedule(String name,Date startTime,Date endTime);

 

    voidschedule(String name,Date startTime,Date endTime,String group);

 

    /**

     *startTime时执行调试,endTime结束执行调度,重复执行repeatCount

    *

     *@paramstartTime

    *           调度开始时间

    *@param repeatCount

    *           重复执行次数

    */

   voidschedule(Date startTime, intrepeatCount);

 

    /**

     *startTime时执行调试,endTime结束执行调度,重复执行repeatCount

    *

     *@paramstartTime

    *           调度开始时间

    *@param endTime

    *           调度结束时间

    *@param repeatCount

    *           重复执行次数

    */

   voidschedule(Date startTime,Date endTime, intrepeatCount);

 

    voidschedule(Date startTime,Date endTime, intrepeatCount,String group);

 

    /**

     *startTime时执行调试,endTime结束执行调度,重复执行repeatCount

    *

     *@paramname

    *            Quartz SimpleTrigger名称

    *@param startTime

    *           调度开始时间

    *@param endTime

    *           调度结束时间

    *@param repeatCount

    *           重复执行次数

    */

   voidschedule(String name,Date startTime,Date endTime, intrepeatCount);

 

    voidschedule(String name,Date startTime,Date endTime, intrepeatCount,String group);

 

    /**

     *startTime时执行调试,endTime结束执行调度,重复执行repeatCount次,每隔repeatInterval秒执行一次

    *

     *@paramstartTime

    *           调度开始时间

    *

     *@paramrepeatCount

    *           重复执行次数

    *@param repeatInterval

    *           执行时间隔间

    */

   voidschedule(Date startTime, intrepeatCount, longrepeatInterval);

 

    /**

     *startTime时执行调试,endTime结束执行调度,重复执行repeatCount次,每隔repeatInterval秒执行一次

    *

     *@paramstartTime

    *           调度开始时间

    *@param endTime

    *           调度结束时间

    *@param repeatCount

    *           重复执行次数

    *@param repeatInterval

    *           执行时间隔间

    */

   voidschedule(Date startTime,Date endTime, intrepeatCount, longrepeatInterval);

 

    voidschedule(Date startTime,Date endTime, intrepeatCount, longrepeatInterval,String group);

 

    /**

     *startTime时执行调试,endTime结束执行调度,重复执行repeatCount次,每隔repeatInterval秒执行一次

    *

     *@paramname

    *            Quartz SimpleTrigger名称

    *@param startTime

    *           调度开始时间

    *@param endTime

    *           调度结束时间

    *@param repeatCount

    *           重复执行次数

    *@param repeatInterval

    *           执行时间隔间

    */

   voidschedule(String name,Date startTime,Date endTime, intrepeatCount, longrepeatInterval);

 

    voidschedule(String name,Date startTime,Date endTime, intrepeatCount, longrepeatInterval,String group);

 

    /**

     *暂停触发器

    *

     *@paramtriggerName

    *           触发器名称

    */

   voidpauseTrigger(String triggerName);

 

    /**

     *暂停触发器

    *

     *@paramtriggerName

    *           触发器名称

    *@param group

    *           触发器组

    */

   voidpauseTrigger(StringtriggerName,String group);

 

    /**

     *恢复触发器

    *

     *@paramtriggerName

    *           触发器名称

    */

   voidresumeTrigger(String triggerName);

 

    /**

     *恢复触发器

    *

     *@paramtriggerName

    *           触发器名称

    *@param group

    *           触发器组

    */

   voidresumeTrigger(String triggerName,String group);

 

    /**

     *删除触发器

    *

     *@paramtriggerName

    *           触发器名称

    *@return

    */

   booleanremoveTrigdger(String triggerName);

 

    /**

     *删除触发器

    *

     *@paramtriggerName

    *           触发器名称

    *@param group

    *           触发器组

    *@return

    */

   booleanremoveTrigdger(String triggerName,String group);

 

}



实现类

packagecom.google.busi.service.impl.busi;

 

importjava.text.ParseException;

importjava.util.*;

 

importorg.quartz.*;

importorg.quartz.Scheduler;

importorg.quartz.impl.triggers.CronTriggerImpl;

importorg.quartz.impl.triggers.SimpleTriggerImpl

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.beans.factory.annotation.Qualifier;

importorg.springframework.stereotype.Service;

 

importcom.google.busi.service.intf.busi.ISchedulerService;

importorg.springframework.transaction.annotation.Transactional;

 

importjavax.annotation.PostConstruct;

 

@Service("schedulerService"

public classSchedulerServiceImplimplementsISchedulerService { 

 

    private static final StringNULLSTRING=null; 

    private static finalDateNULLDATE=null;

 

    @Autowired(required=false)

    private Scheduler scheduler;

   

    @Autowired(required=false)

    @Qualifier("dailyTask")

    private JobDetail jobDetail

 

    @Override 

    public void schedule(String cronExpression) { 

        schedule(NULLSTRING,cronExpression)

   

 

    @Override 

    public void schedule(String name,String cronExpression) { 

        schedule(name,NULLSTRING,cronExpression)

   

 

    @Override 

    public void schedule(String name,String group,String cronExpression) { 

       try

            schedule(name,group, newCronExpression(cronExpression))

       }catch (ParseException e) { 

           throw newIllegalArgumentException(e)

       

    } 

 

    @Override 

    public void schedule(CronExpression cronExpression) { 

        schedule(NULLSTRING,cronExpression)

   

 

    @Override 

    public void schedule(String name,CronExpression cronExpression) { 

        schedule(name,NULLSTRING,cronExpression)

   

 

    @Override 

    public void schedule(String name,String group,CronExpression cronExpression) { 

 

       if(isValidExpression(cronExpression)){ 

 

           if(name ==null|| name.trim().equals("")) { 

                name = UUID.randomUUID().toString()

           

 

            CronTriggerImpl trigger=newCronTriggerImpl()

           trigger.setCronExpression(cronExpression)

 

           TriggerKey triggerKey =newTriggerKey(name,group)

 

           trigger.setJobName(jobDetail.getKey().getName())

           trigger.setKey(triggerKey)

 

            try

               scheduler.addJob(jobDetail, true)

                if(scheduler.checkExists(triggerKey)){ 

                   scheduler.rescheduleJob(triggerKey,trigger)

               }else

                    scheduler.scheduleJob(trigger)

               

            }catch(SchedulerExceptione) { 

               throw newIllegalArgumentException(e)

           

        } 

    } 

 

    @Override 

    public void schedule(Date startTime) { 

        schedule(startTime,NULLDATE)

   

 

    @Override 

    public void schedule(Date startTime,String group) { 

        schedule(startTime,NULLDATE,group)

   

 

    @Override 

    public void schedule(String name,Date startTime) { 

        schedule(name,startTime,NULLDATE)

   

 

    @Override 

    public void schedule(String name,Date startTime,String group) { 

        schedule(name,startTime,NULLDATE,group)

   

 

    @Override 

    public void schedule(Date startTime,Date endTime) { 

        schedule(startTime,endTime,0)

   

 

    @Override 

    public void schedule(Date startTime,Date endTime,String group) { 

        schedule(startTime,endTime,0, group)

   

 

    @Override 

    public void schedule(String name,Date startTime,Date endTime) { 

        schedule(name,startTime,endTime, 0)

   

 

    @Override 

    public void schedule(String name,Date startTime,Date endTime,String group) { 

        schedule(name,startTime,endTime, 0,group)

   

 

    @Override 

    public void schedule(Date startTime, intrepeatCount) { 

        schedule(null,startTime,NULLDATE,0)

   

 

    @Override 

    public void schedule(Date startTime,Date endTime, intrepeatCount) { 

        schedule(null,startTime,endTime, 0)

   

 

    @Override 

    public void schedule(Date startTime,Date endTime, intrepeatCount,String group) { 

        schedule(null,startTime,endTime, 0,group)

   

 

    @Override 

    public void schedule(String name,Date startTime,Date endTime, intrepeatCount) { 

        schedule(name,startTime,endTime, 0,0L)

   

 

    @Override 

    public void schedule(String name,Date startTime,Date endTime, intrepeatCount,String group) { 

        schedule(name,startTime,endTime, 0,0L,group)

   

 

    @Override 

    public void schedule(Date startTime, intrepeatCount, longrepeatInterval) { 

        schedule(null,startTime,NULLDATE,repeatCount,repeatInterval)

   

 

    @Override 

    public void schedule(Date startTime,Date endTime, intrepeatCount, longrepeatInterval) { 

        schedule(null,startTime,endTime, repeatCount,repeatInterval)

    

 

    @Override 

    public void schedule(Date startTime,Date endTime, intrepeatCount, longrepeatInterval,String group) { 

        schedule(null,startTime,endTime, repeatCount,repeatInterval,group)

   

 

    @Override 

    public void schedule(String name,Date startTime,Date endTime, intrepeatCount, longrepeatInterval) { 

        schedule(name,startTime,endTime, repeatCount,repeatInterval,NULLSTRING)

   

 

    @Override 

    public void schedule(String name,Date startTime,Date endTime, intrepeatCount, longrepeatInterval,String group) { 

 

       if(this.isValidExpression(startTime)) { 

 

           if(name ==null|| name.trim().equals("")) { 

                name = UUID.randomUUID().toString()

           

 

            TriggerKey triggerKey =newTriggerKey(name,group)

 

           SimpleTriggerImpl trigger =newSimpleTriggerImpl()

           trigger.setKey(triggerKey)

           trigger.setJobName(jobDetail.getKey().getName())

 

           trigger.setStartTime(startTime)

           trigger.setEndTime(endTime)

           trigger.setRepeatCount(repeatCount)

           trigger.setRepeatInterval(repeatInterval)

 

            try

               scheduler.addJob(jobDetail, true)

                if(scheduler.checkExists(triggerKey)){ 

                   scheduler.rescheduleJob(triggerKey,trigger)

               }else

                   scheduler.scheduleJob(trigger)

               

            }catch(SchedulerExceptione) { 

               throw newIllegalArgumentException(e)

           

        } 

    } 

 

    @Override 

    public void pauseTrigger(String triggerName) { 

        pauseTrigger(triggerName,NULLSTRING)

   

 

    @Override 

    public void pauseTrigger(String triggerName,String group){ 

       try

           scheduler.pauseTrigger(newTriggerKey(triggerName,group));//停止触发器 

       }catch (SchedulerException e) { 

            throw newRuntimeException(e)

       

    } 

 

    @Override 

    public void resumeTrigger(String triggerName) { 

        resumeTrigger(triggerName,NULLSTRING)

   

 

    @Override 

    public void resumeTrigger(String triggerName,String group){ 

       try

           scheduler.resumeTrigger(newTriggerKey(triggerName,group));//重启触发器 

       }catch (SchedulerException e) { 

           throw newRuntimeException(e)

       

    } 

 

    @Override 

    public boolean removeTrigdger(String triggerName) { 

       returnremoveTrigdger(triggerName,NULLSTRING)

   

 

    @Override 

    public boolean removeTrigdger(String triggerName,String group){ 

        TriggerKey triggerKey =newTriggerKey(triggerName,group)

        try

           scheduler.pauseTrigger(triggerKey);//停止触发器 

           returnscheduler.unscheduleJob(triggerKey);//移除触发器 

       }catch (SchedulerException e) { 

           throw newRuntimeException(e)

       

    } 

 

    private boolean isValidExpression(finalCronExpressioncronExpression) { 

 

        CronTriggerImpl trigger =newCronTriggerImpl()

       trigger.setCronExpression(cronExpression)

 

       Date date =trigger.computeFirstFireTime(null)

 

        returndate !=null&&date.after(newDate())

   

 

    private boolean isValidExpression(finalDate startTime){ 

 

        SimpleTriggerImpl trigger =newSimpleTriggerImpl()

        trigger.setStartTime(startTime)

 

       Date date =trigger.computeFirstFireTime(null)

 

        returndate !=null&&date.after(newDate())

    }



五:动态设置cron表达式

 

/**

   *设置订单清理时间

  */

 @PutMapping(value="/age")

  @ResponseBody

  public String setSubsNoPayAge(@RequestBodyReqEntity reqEntity) {

   try {

   JSONObject reqBody =reqEntity.getReqBody();

   Integer age = reqBody.getInteger("age")/1;

   ISchedulerService schedulerService =ApplicationContextUtil.getBean("schedulerService",ISchedulerService.class);

      schedulerService.schedule(InitCronTriggerFactoryBean.SUBS_NOPAY_TRIGGER,DateUtil.parseExpression(age));

 

       if(age >0) {

           age = age*60;//分钟转化为秒

          BaseConfig baseConfig =newBaseConfig();

          baseConfig.setConfigId(Constants.NOPAY_SUBS_AGE);

          baseConfig.setConfigValue(age.toString());

          baseConfigService.updateBaseConfig(baseConfig);

      }

      

  returnWebUtil.formatResponseParams(CodeDefine.EXEC_OK, null,baseCodeService);

} catch(Exception e) {

   logger.error("订单发货失败!",e);

   returnWebUtil.formatResponseParams(CodeDefine.SERVER_ERROR, null,baseCodeService);

}

  }