网上搜集加自己总结,闲话少说:
使用Quartz实现项目中的任务调度的基本步骤:
1、创建jobDetail作业任务
2、创建任务触发器
3、创建任务调度工厂来启动触发器
1、创建JobDetail
JobDetailBean:
用户可以直接使用Quartz的JobDetail在Spring中配置一个JobDetail Bean,但是JobDetail使用带参的构造函数,对于习惯通过属性配制的Spring用户来说存在使用上的不便。为此Spring通过扩展JobDetail提供了一个更具Bean风格的JobDetailBean。
JobDetailBean扩展于Quartz的JobDetail。使用该Bean声明JobDetail时,Bean的名字即是任务的名字,如果没有指定所属组,就使用默认组。除了JobDetail中的属性外,还定义了以下属性:
JobClass:类型为Class,实现Job接口的任务。
BeanName:默认为Bean的ID名,通过该属性显式指定Bean名称,它对应任务的名称。
JobDateAsMap:类型为Map,为任务所对应的JobDataMap提供值。之所以需要提供这个属性,是因为用户无法在Spring配置文件为JobDataAsMap类型的属性提供信息,所以Spring通过jobDataAsMap设置JobDataMap的值。
ApplicationContextJobDataKey:用户可以将Spring ApplicationContext的引用保存到JobDataMap中,以便在Job的代码中访问ApplicationContext。为了达到这个目的,用户需要指定一个键,用以在jobDataAsMap中保存 ApplicationContext,如果不设置此键,JobDetailBean就不将ApplicationContext放入到JobDataMap中。
JobListenerNames;类型为String[],指定注册在Scheduler中的JobListeners名称,以便让这些监听器对本任务的事件进行监听。
<bean id="autoSendJob" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass"> <value>com.techson.himsnanhwa.admin.scheduler.AutoSendScheduler</value> </property> <property name="applicationContextJobDataKey" value="applicationContext"/> <property name="jobDataAsMap"> <map> <entry key="days"> <value>1</value> </entry> <entry key="isAutoSend"> <value>false</value> </entry> <entry key="isDebug"> <value>false</value> </entry> </map> </property> </bean>
days、isAutoSend、isDebug是类中AutoSendScheduler中自己定义的属性!
public class AutoSendScheduler extends QuartzJobBean { private int days=1; private Boolean isAutoSend; private Boolean isDebug; protected void executeInternal(JobExecutionContext arg0) { Map dataMap = arg0.getJobDetail().getJobDataMap(); ApplicationContext appCtx = (ApplicationContext)dataMap.get("applicationContext"); 。。。 } }
MethodInvokingJobDetailFactoryBean :
Spring 为我们提供了 MethodInvokingJobDetailFactoryBean ,借由该 FactoryBean ,我们可以将一个 Bean 的某种方法封装成满足 Quartz 要求的 Job .
<bean id="jobDetail_1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="myService"> <property name="targetMethod" value="doJob"> <property name="concurrent" value="false"> </bean> <bean id="myService" class="com.test.myService" />
public class MyService(){ public void doJob(){ System.out.println("doJobing....."); } }
jobDetail_1将MyService#doJob()封装成一个任务,同时通过concurrent属性指定任务的类型,默认情况下封装为无状态的任务,如果希望目标封装为有状态的任务,仅需要将concurreng设置成false就可以了。
Spring通过名为concurrent的属性指定任务的类型 ,能够更直接地描述任务执行的方式(有状态的任务不能并发执行,无状态的任务可并发执行 )
doJob() 方法即可以是 static ,也可以是非 static 的,但不能拥有方法入参 。通过 MethodInvokingJobDetailFactoryBean 产生的 JobDetail 不能被序列化,所以不能不持久化到数据库中,如果希望使用持久化任务,用户只能创建正规的 Quartz 的 Job 实现了。
2、创建触发器:
简单触发器:
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail"> <ref bean="autoSendJob"/> </property> <!-- 工作执行的频率,以毫秒为单位 --> <property name="repeatInterval"> <value>60000</value> </property> </bean>
简单触发器SimpleTriggerBean基本属性repeatInterval、repeatCount
这里我们设置了每隔一分钟执行一次我们创建的工作。 SimpleTriggerBean 只能让我们指定工作执行的频率,不能让我们指定工作执行的具体时间。比方说,我们要求在每天的晚上 10 点执行某个具体的工作,那么 SimpleTriggerBean 就不能满足我们的需求了,这个时候我们需要使用另外一个 bean : CronTriggerBean 。
Cron触发器:
CronTrigger
支持比 SimpleTrigger
更具体的调度,而且也不是很复杂。基于 cron 表达式,CronTrigger
支持类似日历的重复间隔,而不是单一的时间间隔。
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="autoSendJob"/> </property> <property name="cronExpression"> <value>0 0 22 * * ? *</value> </property> </bean>
这个配置指定了每天晚上 10 点执行我们的工作,使用 CronTriggerbean 我们可以精确的控制任务运行的时间,这个运行时间我们是通过 cronExpression 属性指定的,它是一个 cron 表达式,下面说一下这个表达式的语法。
一个 cron 表达式有 6 个必选的元素和一个可选的元素,各个元素之间是以空格分隔的,从左至右,这些元素的含义如下表所示:
* :代表所有可取的值,比如说,如果分钟为 * ,那么就表示每一分钟;
? :只有月份中的天数和星期中的天数可以使用?来表示,因为“月份中的天数”和“星
期中的天数”不能同时设值,所以我们可以通过?来表明不想设置的那个元素 ;
- :用来指定一个范围类的值,比如说,小时为 ”10-12” ,它就表示 10 点、 11 点、 12 点
, :逗号用来分隔一个元素的多个值,比如说“星期中的天数”为 "MON,WED,FRI" ,
它就表示周一、周三和周五。
/ :斜杠用来表示间隔,比如说,秒数为 5/10 ,那么它就表示第 5 秒、第 15 秒、第
25 秒、第 35 秒、第 45 秒和第 55 秒。斜杠前的数字表示起始位置,后面的数字表
示每次增长的数量。
L :仅用在“月份中的天数”和“星期中的天数”元素中。如果是前者,它代表某月的
最后一天;如果是后者,它就表示是周六。有一点特别的,当表示“星期中的天数”
时, L 可以和数字一起用,比如 ”6L” ,它就表示这个月的最后一个星期五。
W :只能用来表示“月份中的天数”,和数字一起使用。比如说 15W ,它就表示离这
个月 15 号最近的工作日。使用 W 时,“月份中的天数”必须为一个指定的日期,
而不能是一个范围的日期。
# :只能用来表示“星期中的天数”。例如 5#4 ,它表示某个月中第四个星期四, 2#1
表示某个月中第一个星期一。 # 前面的数字代表星期,后面的数字表示是第几个。
3、创建触发器调度工厂
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- 一组触发器 --> <property name="triggers"> <list> <ref bean="simpleTrigger"/> </list> </property> </bean>
。。。
参考:
http://blog.csdn.net/CMTobby/archive/2007/09/21/1795257.aspx
http://www.easyjf.com/blog/html/20071230/1015808.html
http://www.iteye.com/topic/144515