`

spring动态定时任务

阅读更多

什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。
这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下 Quartz在Spring中的动态定时,发现<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
          <property name="jobDetail" ref="schedulerJobDetail"/>
          <property name="cronExpression">
              <value>0/10 * * * * ?</value>
          </property>
     中cronExpression 是关键,如果可以动态设置cronExpression的值,也就说如果我们可以直接调用CronTriggerBean中设置 cronExpression的方法,就可以顺利解决问题了。
熟悉1的朋友可以跳过不看,下面2、3是动态定时任务的具体实现。
1. Quartz在Spring中的简单配置
Spring配置文件:
     <bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
         <property name="targetObject" ref="scheduleInfoAction"/>
         <property name="targetMethod" value="simpleJobTest"/>
         <property name="concurrent" value="false"/>
     </bean>
     <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
          <property name="jobDetail" ref="schedulerJobDetail"/>
          <property name="cronExpression">
              <value>0/10 * * * * ?</value>
          </property>
      </bean>
     <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
         <property name="triggers">
             <list>
                 <ref local="cronTrigger"/>
             </list>
         </property>
</bean>
在上面的配置中设定了
① targetMethod: 指定需要定时执行scheduleInfoAction中的simpleJobTest()方法
② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个 job完成之前开始。
③ cronExpression:0/10 * * * * ?表示每10秒执行一次,具体可参考附表。
④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。
scheduleInfoAction中的simpleJobTest()方法
注意:此方法没有参数,如果scheduleInfoAction有两个方法simpleJobTest()和 simpleJobTest(String argument),则spring只会去执行无参的simpleJobTest().
public void simpleJobTest() {
         log.warn("uh oh, Job is scheduled !'" + "' Success...");
     }
2.Quartz在 Spring中动态设置cronTrigger 方法一
Spring配置文件:
<bean id="scheduleInfoAction" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction">
         <property name="scheduler" ref="schedulerFactory"/>
         <property name="scheduleInfoManager" ref="scheduleInfoManager"/>
     </bean>
     <bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
         <property name="targetObject" ref="scheduleInfoAction"/>
         <property name="targetMethod" value="reScheduleJob"/>
         <property name="concurrent" value="false"/>
     </bean>
     <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
          <property name="jobDetail" ref="schedulerJobDetail"/>
          <property name="cronExpression">
              <value>0/10 * * * * ?</value>
          </property>
      </bean>
     <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
         <property name="triggers">
             <list>
                 <ref local="cronTrigger"/>
             </list>
         </property>
</bean>
scheduleInfoAction中的reScheduleJob ()方法及相关方法
① reScheduleJob读取数据库,获得自定义定时器调度时间():
     private void reScheduleJob() throws SchedulerException, ParseException {
         // 运行时可通过动态注入的scheduler得到trigger
         CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(
                "cronTrigger", Scheduler.DEFAULT_GROUP);
         String dbCronExpression = getCronExpressionFromDB();
         String originConExpression = trigger.getCronExpression();
     // 判断从DB中取得的任务时间 (dbCronExpression)和现在的quartz线程中的任务时间(originConExpression)是否相等
     // 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新 rescheduleJob
         if(!originConExpression.equalsIgnoreCase(dbCronExpression)){
             trigger.setCronExpression(dbCronExpression);
             scheduler.rescheduleJob("cronTrigger", Scheduler.DEFAULT_GROUP, trigger);
         }
     // 下面是具体的job内容,可自行设置
     // executeJobDetail();
}
② getCronExpressionFromDB():从数据库中获得dbCronExpression的具体代码,由于使用了 scheduleInfoManager,所以要在定义相应的setter方法
     private String getCronExpressionFromDB(){
         String sql="from ScheduleInfo scheduleInfo where 1=1 ";
         sql=sql+" and scheduleInfo.infoId = '"+"1" + "'";
         List scheduleList = scheduleInfoManager.queryScheduleInListBySql(sql);
         ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleList.get(0);
         String dbCronExpression = scheduleInfo.getCronExpression();
         return dbCronExpression;
}
③ 在spring配置文件的scheduleInfoAction配置了相应的 property(scheduler/ scheduleInfoManager), 要为其设置setter方法
     private Scheduler scheduler;
     // 设值注入,通过setter方法传入被调用者的实例 scheduler
     public void setScheduler(Scheduler scheduler) {
         this.scheduler = scheduler;
    }
     private ScheduleInfoManager scheduleInfoManager;
     // 设值注入,通过setter方法传入被调用者的实例 scheduleInfoManager
     public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){
         this.scheduleInfoManager = scheduleInfoManager;
     }
3. Quartz在Spring中动态设置cronTrigger方法二
在上面的2中我们可以看到,尽管已经可以动态进行rescheduleJob了,不过依然需要我们设置一个cronExpression,如果尝 试一下拿掉spring配置中的
         <property name="cronExpression">
              <value>0/10 * * * * ?</value>
          </property>
则容器(如tomcat)启动时会报错。
实际中我们希望tomcat启动时就可以直接去读数据库,拿到相应的 dbCronExpression,然后定时执行一个job,而不希望配置初始的cronExpression ,观察下面的CronTriggerBean,考虑到cronExpression需要初始化,如果设定一个类 InitializingCronTrigger继承 CronTriggerBean,然后在这个类中做一些读取DB的初始化工作(设置cronExpression),问题就可以解决了。
Spring配置文件:
<bean id="scheduleInfoAction" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction">
         <property name="scheduler" ref="schedulerFactory"/>
         <property name="scheduleInfoManager" ref="scheduleInfoManager"/>
     </bean>
     <bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
         <property name="targetObject" ref="scheduleInfoAction"/>
         <property name="targetMethod" value="reScheduleJob"/>
         <property name="concurrent" value="false"/>
     </bean>
    <bean id="cronTrigger" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction.InitializingCronTrigger">
          <property name="jobDetail" ref="schedulerJobDetail"/>
         <!--<property name="cronExpression">
              <value>0/10 * * * * ?</value>
          </property>-->
          <property name="scheduleInfoManager" ref="scheduleInfoManager"/>
      </bean>
     <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
         <property name="triggers">
             <list>
                 <ref local="cronTrigger"/>
             </list>
         </property>
</bean>
InitializingCronTrigger中的相关方法
注意:在注入scheduleInfoManager属性的时候,我们可以去读取DB任务时间(之所以放在setter方法中,是因为需要在设置 scheduleInfoManager后进行getCronExpressionFromDB(),否则,也可以①②逻辑把放在类的构造函数中).
注意InitializingCronTrigger必须extends CronTriggerBean.
public class InitializingCronTrigger extends CronTriggerBean implements Serializable {
     private ScheduleInfoManager scheduleInfoManager;
     // 设值注入,通过setter方法传入被调用者的实例 scheduleInfoManager
     public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){
         this.scheduleInfoManager = scheduleInfoManager;
         // 因为在getCronExpressionFromDB使用到了 scheduleInfoManager,所以
         // 必须上一行代码设置scheduleInfoManager 后进行getCronExpressionFromDB
         String cronExpression = getCronExpressionFromDB ();    // ①
         // 因为extends CronTriggerBean ,此处调用父类方法初始化cronExpression
        setCronExpression(cronExpression);                     // ②
}
     private String getCronExpressionFromDB(){
         String sql="from ScheduleInfo scheduleInfo where 1=1 ";
         sql=sql+" and scheduleInfo.infoId = '"+"1" + "'";
         List scheduleList = scheduleInfoManager.queryScheduleInListBySql(sql);
         ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleList.get(0);
         String dbCronExpression = scheduleInfo.getCronExpression();
         return dbCronExpression;
}
……
}
附表:
"0 0 12 * * ?" 每天中午12点触发
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
"0 15 10 15 * ?" 每月15日上午10:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

分享到:
评论

相关推荐

    quartz spring动态定时任务,可以直接在tomcat上面部署运行

    Quartz和Spring结合实现动态定时任务是企业级应用中常见的一种技术组合,它允许开发者灵活地定义、管理和执行定时任务。Quartz是一个开源的作业调度框架,而Spring框架则为Java应用程序提供了强大的依赖注入(DI)和...

    spring动态分配定时任务

    2.通过Spring是JAR-quartz写的一个定时任务 1)普通的定时任务,定时完成指定的任务 2)通过前台动态分配定时任务 可指定多个任务,可同时执行任务,可以精确到时分秒扫描并执行任务 3)可以完成稍微复杂点的任务 ...

    Spring Quartz 动态暂停、恢复、修改定时任务

    Spring Quartz 动态暂停、恢复、修改定时任务的一个demo,使用maven构建,框架采用spring springmvc jpa,数据库mysql,含数据库脚本,运行可用,页面访问地址http://localhost:8080/quartz_demo/quartz/list

    spring设置动态定时任务

    【Spring 动态定时任务详解】 在 Spring 中,动态定时任务是一种允许用户在不重启服务的情况下,自由调整任务执行时间的机制。这种功能通常通过集成第三方定时任务框架,如 Quartz,来实现。Quartz 是一个功能强大...

    spring+quartz动态定时任务创建 +mybatis

    **Spring+Quartz动态定时任务创建** 将Spring与Quartz结合,我们可以方便地在运行时动态创建和修改定时任务。首先,我们需要在Spring配置文件中声明一个SchedulerFactoryBean,然后定义JobDetail和Trigger,分别表示...

    spring动态配置定时任务

    在Java Spring框架中,动态配置定时任务是一项非常实用的功能,它允许我们根据需求灵活地更改或添加定时任务,而无需每次改动都重启应用。本文将深入探讨如何在Spring中实现这种动态配置,以及如何结合数据库来管理...

    springboot动态配置定时任务(schedule)

    在Spring Boot应用中,动态配置定时任务是提升系统灵活性和可维护性的重要手段。Spring Boot集成了Spring Framework的TaskExecution和TaskScheduling模块,使得我们可以方便地创建和管理定时任务。本文将深入探讨...

    spring+springMVC+mybatis+quartz动态定时任务创建

    在IT行业中,构建高效、可扩展的Web应用是至关重要的,而"spring+springMVC+mybatis+quartz动态定时任务创建"就是一个常见的技术栈,用于实现这样的目标。这个组合充分利用了各组件的优势,提供了强大的后端服务支持...

    Spring3.0定时任务简单实例web工程

    在Spring框架中,定时任务是实现自动化操作的重要手段,它允许开发者在特定的时间间隔执行特定的任务,例如数据清理、报表生成等。在本实例中,我们关注的是Spring 3.0版本中的定时任务功能,这是一个基于Web工程的...

    spring自带定时任务程序

    给定的压缩包可能包含了一个关于如何配置、使用和测试Spring定时任务的文档。这个文档应该详细介绍了每个步骤,包括如何在Spring环境中注册和启动定时任务,如何编写带有`@Scheduled`注解的方法,以及如何编写测试...

    spring xml 定时任务

    在Spring框架中,XML配置是传统且广泛使用的方式来设置应用的组件和行为,包括实现定时任务。定时任务在软件开发中扮演着重要角色,它允许应用程序在预设的时间执行特定的任务,例如数据清理、日志归档或者发送通知...

    Spring中定时任务

    结合Eclipse和Maven,创建Spring定时任务项目时,你需要: 1. 创建一个新的Maven项目,并添加Spring的相关依赖,如`spring-context`, `spring-context-support`(对于Spring Task),以及`quartz`和`spring-quartz`...

    springboot定时任务的动态开启关闭

    以上就是Spring Boot中实现定时任务动态开启和关闭的基本步骤。在实际开发中,我们还需要考虑任务的异常处理、日志记录以及可能的并发问题。理解并掌握这些知识点对于构建高效稳定的后台服务至关重要。

    Spring定时任务管理

    Spring定时任务的几种实现,欢迎交流!

    spring整合java quartz实现动态定时任务的前台网页配置与管理

    可以通过quartz和spring的简单配置即可完成,但如果要改变任务的执行时间、频率,废弃任务等就需要改变配置甚至代码需要重启服务器,这里介绍一下如何通过quartz与spring的组合实现动态的改变定时任务的状态的一个...

    spring动态定时调度任务

    在`ScheduleInfoAction`的`reSchdeuleJob()`方法中,我们可以动态获取和设置定时任务的cron表达式。例如,从数据库中读取用户的自定义调度时间,然后更新`CronTriggerBean`的`cronExpression`,从而达到动态调整任务...

    Spring 定时任务源码(spring 三种定时任务的实现方式)

    在Spring框架中,定时任务是实现系统自动化运行关键任务的重要工具。Spring提供了多种方式来创建和管理定时任务,...在chapter13目录下的文件可能包含了这些源码示例,你可以逐一研究,加深对Spring定时任务的理解。

    Spring普通定时任务和动态设置定时任务

    ### Spring 普通定时任务与动态设置定时任务详解 #### 一、Spring 定时任务简介 在软件开发过程中,经常会遇到需要周期性执行的任务,例如数据备份、定时发送邮件等。对于这类需求,Spring 提供了一种简单且灵活的...

    基于Spring的Quartz动态定时任务增删改查

    基于Spring的Quartz动态定时任务增删改查,代码简洁。后端采用SpringMvc+Spring+Mybatis+Quartz,前端采用Bootstrap框架,数据库采用MySQL;完成定时任务动态任务初始化,增删改查

Global site tag (gtag.js) - Google Analytics