Quartz
在
Spring
中动态设置
cronExpression
什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。
这样总不能修改配置文件每定制个定时任务就增加一个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
触发
至于每个符号 看看例子就好了.
很简单了.
以上内容转载至:http://hi.baidu.com/vip099/blog/item/51bbb03d555f5702bba16766.html
分享到:
相关推荐
本文将详细介绍如何在Spring中设置动态定时任务,特别关注如何动态设置`cronExpression`。 首先,我们需要了解Quartz在Spring中的基本配置。在Spring配置文件中,我们通常创建三个主要的bean: 1. `...
总结来说,Spring通过Quartz提供了强大的定时任务管理能力,包括动态设置定时任务的执行时间。通过正确配置`MethodInvokingJobDetailFactoryBean`、`CronTriggerBean`以及`SchedulerFactoryBean`,并结合业务接口...
2.通过Spring是JAR-quartz写的一个定时任务 1)普通的定时任务,定时完成指定的任务 2)通过前台动态分配定时任务 可指定多个任务,可同时执行任务,可以精确到时分秒扫描并执行任务 3)可以完成稍微复杂点的任务 ...
使用 Spring Quartz,我们可以轻松地实现动态配置时间,触发相应的任务,从而提高系统的灵活性和可维护性。 系统架构 在本文中,我们假设了一个基于 Struts、Spring 和 Hibernate 的系统架构,旨在提供一个更加...
在Java Spring框架中,动态配置定时任务是一项非常实用的功能,它允许我们根据需求灵活地更改或添加定时任务,而无需每次改动都重启应用。本文将深入探讨如何在Spring中实现这种动态配置,以及如何结合数据库来管理...
在Spring Boot应用中,动态配置定时任务是提升系统灵活性和可维护性的重要手段。Spring Boot集成了Spring Framework的TaskExecution和TaskScheduling模块,使得我们可以方便地创建和管理定时任务。本文将深入探讨...
Java Spring Quartz 动态定时任务是企业级应用中常见的需求,用于执行周期性的后台作业,如数据同步、报表生成等。Spring与Quartz的结合使用,使得我们可以方便地在Spring框架下管理定时任务,同时还能实现任务的...
**Spring+Quartz动态定时任务创建** 将Spring与Quartz结合,我们可以方便地在运行时动态创建和修改定时任务。首先,我们需要在Spring配置文件中声明一个SchedulerFactoryBean,然后定义JobDetail和Trigger,分别表示...
以上就是Spring Boot中实现定时任务动态开启和关闭的基本步骤。在实际开发中,我们还需要考虑任务的异常处理、日志记录以及可能的并发问题。理解并掌握这些知识点对于构建高效稳定的后台服务至关重要。
在这两种方式中,Spring框架提供了自己的定时任务工具Spring Task,以及与专业定时任务框架Quartz集成的能力。 首先,对于Java自带的定时任务实现,我们可以使用java.util.Timer和java.util.TimerTask类。Timer类...
在IT行业中,构建高效、可扩展的Web应用是至关重要的,而"spring+springMVC+mybatis+quartz动态定时任务创建"就是一个常见的技术栈,用于实现这样的目标。这个组合充分利用了各组件的优势,提供了强大的后端服务支持...
基于Spring的Quartz动态定时任务增删改查,代码简洁。后端采用SpringMvc+Spring+Mybatis+Quartz,前端采用Bootstrap框架,数据库采用MySQL;完成定时任务动态任务初始化,增删改查
Spring定时任务基础 Spring的定时任务功能是通过`org.springframework.scheduling`包中的类来实现的,主要涉及`TaskScheduler`和`TaskExecutor`接口。`TaskScheduler`用于定时任务的调度,而`TaskExecutor`则处理...
可以通过quartz和spring的简单配置即可完成,但如果要改变任务的执行时间、频率,废弃任务等就需要改变配置甚至代码需要重启服务器,这里介绍一下如何通过quartz与spring的组合实现动态的改变定时任务的状态的一个...
### Spring 普通定时任务与动态设置定时任务详解 #### 一、Spring 定时任务简介 在软件开发过程中,经常会遇到需要周期性执行的任务,例如数据备份、定时发送邮件等。对于这类需求,Spring 提供了一种简单且灵活的...
在Spring框架中,定时任务是实现系统自动化运行关键任务的重要工具。Spring提供了多种方式来创建和管理定时任务,...在chapter13目录下的文件可能包含了这些源码示例,你可以逐一研究,加深对Spring定时任务的理解。
`@Scheduled`注解是Spring Framework中用于创建定时任务的重要工具,它允许开发者在不重启应用的情况下,实现定时任务的动态配置,特别是修改cron表达式来调整执行周期。 在Spring中,定时任务主要通过`@Scheduled`...
在Spring框架中,定时任务的实现提供了多种方式,如基于Java Timer API的定时任务和基于Quartz库的定时任务。这两种方法各有优缺点,适用于不同的场景。以下将详细讲解这两种方式。 1. 基于Java Timer API的定时...