天天看点

Quartz在Spring中动态设置cronExpression (spring设置动态定时任务)------转帖

什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。

这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下quartz在spring中的动态定时,发现

              0/10 ?

     中cronexpression是关键,如果可以动态设置cronexpression的值,也就说如果我们可以直接调用crontriggerbean中设置cronexpression的方法,就可以顺利解决问题了。

熟悉1的朋友可以跳过不看,下面2、3是动态定时任务的具体实现。

<a></a>

1. quartz在spring中的简单配置

spring配置文件:

         targetmethod" value="simplejobtest"/&gt;

          cronexpression**"&gt;

在上面的配置中设定了

① 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方法一

         scheduler**" ref="schedulerfactory"/&gt;

         scheduleinfomanager**" ref="scheduleinfomanager"/&gt;

         reschedulejob**"/&gt;

     crontrigger**" class="org.springframework.scheduling.quartz.crontriggerbean" &gt;

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配置中的

         cronexpression**"&gt;

则容器(如tomcat)启动时会报错。

实际中我们希望tomcat启动时就可以直接去读数据库,拿到相应的dbcronexpression,然后定时执行一个job,而不希望配置初始的cronexpression ,观察下面的crontriggerbean,考虑到cronexpression需要初始化,如果设定一个类initializingcrontrigger继承crontriggerbean,然后在这个类中做一些读取db的初始化工作(设置cronexpression),问题就可以解决了。

    crontrigger**" class="com.lively.happyoa.jobs.webapp.action.scheduleinfoaction.**initializingcrontrigger**"&gt;

          scheduleinfomanager**" ref="scheduleinfomanager"/&gt;

initializingcrontrigger中的相关方法

注意:在注入scheduleinfomanager属性的时候,我们可以去读取db任务时间(之所以放在setter方法中,是因为需要在设置scheduleinfomanager后进行getcronexpressionfromdb(),否则,也可以①②逻辑把放在类的构造函数中).

注意initializingcrontrigger必须extends crontriggerbean.

public class initializingcrontrigger extends crontriggerbean implements serializable {

         // 因为在getcronexpressionfromdb使用到了scheduleinfomanager,所以

         // 必须上一行代码设置scheduleinfomanager后进行getcronexpressionfromdb

         string cronexpression = getcronexpressionfromdb ();    // ①

         // 因为extends crontriggerbean ,此处调用父类方法初始化cronexpression

        setcronexpression(cronexpression);                     // ②

……

附表:

“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触发

至于每个符号 看看例子就好了.很简单了.