Spring 调度任务
Java的Timer类和OpenSymphony的Quartz调度器是两个流行的调度API。Spring为这两个调度器提供了一个抽象层,可以更容易的使用他们
(1)使用java Timer调度任务
从jdk1.3开始提供java.util.Timer类实现基本的调度功能,这个类允许你调度一个任务(通过java.util.TimerTask子类定义)按任意周期运行
1.创建一个定时任务
使用java Timer调度第一步是从java.util.TimerTask派生一个任务,如:
public class EmailReportTask exetends TimerTask
{
public EmailReportTask()
{}
public void run()
{
courseService.sendCourseEnrollmentReport();
}
private CourseService courseService;
public void setCourseService(CourseService courseService)
{
this. courseService= courseService;
}
}
2.在Spring 配置文件中声明EmailReportTask
<bean id=”reportTimerTask” class=”com.springinaction.training.schedule.EmailReportTask”>
<property name=” courseService”>
<ref bean=” courseService”/>
</property>
</bean>
声明本身只是将EmailReportTask放到应用上下文,并在courseService属性装配courseService Bean。在调度之前不会做任何事。
3.调度定时任务
Spring的ScheduledTimerTimerTask定义了一个定时器任务的运行周期。应该如下装配一个ScheduledTimerTask
<bean id=”scheduledReportTask” class=”org.springframework.scheduling.timer.ScheduledTimerTask”>
<property name=”timerTask”>
<ref bean =”reportTimerTask”/>
</property>
<property name=”period”>
<value>86400000</value>
</property>
</bean>
timerTask告诉ScheduledTimerTask运行哪个TimerTask,这里该装配属性指向reportTimerTask的一个引用。属性period告诉ScheduledTimerTask以怎样的频率调用TimerTask的run()方法。这个属性以毫秒作为单位,86400000指定该任务每24小时运行一次。
4.启动定时器
Spring 的TimerFactoryBean负责启动定时任务。按以下方式在Spring配置文件里声明它
<bean class=”org.springframework.scheduling.timer. ”>
<property name=”scheduledTimerTask”>
<list>
<ref bean =”scheduledReportTask”/>
</list>
</property>
</bean>
属性scheduledTimerTasks 要求一个需要启动的定时器任务列表。ScheduledTimerTask有一个delay属性,允许你指定当任务第一次运行之前应该等多久。如,EmailReportTask的第一次运行延迟1小时。
<bean id=”scheduledReportTask” class=”org.springframework.scheduling.timer.ScheduledTimerTask”>
<property name=”timerTask”>
<ref bean=”reportTimerTask”/>
</property>
<property name=”period”>
<value>86400000</value>
</property>
<property name=”delay”>
<value>3600000</value>
</property>
Java Timer可以指定任务执行的频率,但是无法精确指定何时运行。
(2)使用Quartz调度器
Quartz比java Timer更好的地方在于它允许调度一个任务在某个特定的时间或者日期执行
1.创建一个任务
任务类需要从Spring 的QuartzJobBean类继承,如:
Public class EmailReportJob extends QuartzJobBean
{
Protected void executeInternal(JobExecutionContext context)throws JobExecutionException
{
courseService.sendCourseEnrollmentReport();
}
private CourseService courseService;
public void setCourseService(CourseService courseService)
{
this. courseService= courseService;
}
}
QuartzJobBean是Quartz中与java的TimerTask等价的类。它实现了org.quartz.Job接口,executeInternal()方法定义了在预定的时刻来临时执行那些动作。
2.Spring配置文件中声明
<bean id=”reportJob” class=”org.springframework.scheduling.quartz.JobDetailBean”>
<property name=” jobClass”>
<value>com.springinaction.training.schedule.EmailReportJob</value>
</property>
<property name=”jobDataAsMap”>
<map>
<entry key=” courseService”>
<ref bean =” courseService”/>
</entry>
</map>
</property>
</bean>
3.调度任务
Quartz的org.quartz.Trigger类描述了何时及怎样的频率来的运行一个Quartz工作。Spring 提供 了两个触发器,SimpleTriggerBean和CronTriggerBean。
SimpleTriggerBean和ScheduledTimerTask类似,用它来指定一个工作应以怎样的频率运行,及第一次运行工作前应等多久。Spring装配如下:
<bean id=”simpleReportTrigger” class=”org.springframework.scheduling.quartz.SimpleTriggerBean”>
<property name=”jobDetail”>
<ref bean =”reportJob”>
</property>
<property name=”startDelay”>
<value>3600000</value>
</property>
<property name=”repeatInterval”>
<value>86400000</value>
</property>
CronTriggerBean允许更精确的控制任务的运行时间。如果要在每天的6:00运行任务可以按照以下方式声明一个CronTriggerBean:
<bean id=”cronReportTrigger” class=”org.springframework.scheduling.quartz.CronTriggerBean”>
<property name=”jobDetail”>
<ref bean =”reportJob”>
</property>
<property name=”cronExpression”>
<value>0 0 6 * * ?</value>
</property>
</bean>
和SimpleTriggerBean一样,jobDetail属性告诉触发器调度哪一个工作,属性cronExpression告诉触发器何时触发。一个cron表达式至少有6个由空格分隔的时间元素(最多7个)从左到右元素定义如下
1。秒(0-59)
2。分(0-59)
3。小时(0-23)
4。月份中的日期(1-31)
5。月份(1-12 或 JAN-DEC)
6。星期(1-7 或 SUN-SAT)
7。年份(1970-2099)
每一个元素都可以显示规定的一个值,一个区间(9-14),一个列表(9,12,14)或一个通配符(*)月份中的日期和星期中的日期这两个元素时互斥的一起应该通过设置一个问号(?)来表明不想设置那个字段
对于cronReportTrigger我们设置的cronExpression为 0 0 6 * * ?可以读作任意月份任何日期的6时0分0秒执行触发器
4.启动任务
Spring的SchedulerFactoryBean时Quartz中与TimerFactoryBean的等价类。如下在Spring的配置文件中声明:
<bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
<property name=”triggers”>
<list>
<ref bean =”cronReportTrigger”/>
</list>
</property>
Triggers属性接收一组触发器
调度单次方法调用
为了达到这个目的Spring提供了MethodInvokingTimerTaskFactoryBean和MethodInvokingJobDetailFactoryBean,分别可以使用java的Timer支持或者Quartz调度器对方法进行调度。
1.<bean id=”scheduledReportTask” class=”org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean”>
<property name=”targetObject”>
<ref bean=”courseService”/>
</property>
<property name=”targetMethod”>
<value>sendCourseEnrollmentReport</value>
</property>
</bean>
2.<bean id=”scheduledReportTask” class=”org.springframework.scheduling.timer.MethodInvokingJobDetailFactoryBean”>
<property name=”targetObject”>
<ref bean=”courseService”/>
</property>
<property name=”targetMethod”>
<value>sendCourseEnrollmentReport</value>
</property>
</bean>