什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。
这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下quartz在spring中的动态定时,发现
0/10 ?
中cronexpression是关键,如果可以动态设置cronexpression的值,也就说如果我们可以直接调用crontriggerbean中设置cronexpression的方法,就可以顺利解决问题了。
熟悉1的朋友可以跳过不看,下面2、3是动态定时任务的具体实现。
<a></a>
1. quartz在spring中的简单配置
spring配置文件:
targetmethod" value="simplejobtest"/>
cronexpression**">
在上面的配置中设定了
① 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"/>
scheduleinfomanager**" ref="scheduleinfomanager"/>
reschedulejob**"/>
crontrigger**" class="org.springframework.scheduling.quartz.crontriggerbean" >
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**">
则容器(如tomcat)启动时会报错。
实际中我们希望tomcat启动时就可以直接去读数据库,拿到相应的dbcronexpression,然后定时执行一个job,而不希望配置初始的cronexpression ,观察下面的crontriggerbean,考虑到cronexpression需要初始化,如果设定一个类initializingcrontrigger继承crontriggerbean,然后在这个类中做一些读取db的初始化工作(设置cronexpression),问题就可以解决了。
crontrigger**" class="com.lively.happyoa.jobs.webapp.action.scheduleinfoaction.**initializingcrontrigger**">
scheduleinfomanager**" ref="scheduleinfomanager"/>
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触发
至于每个符号 看看例子就好了.很简单了.