spring调度任务

Spring调度任务


目录
1 调度任务 1
1.1 实现任务调度的背景 1
1.2 使用JAVA TIMER调度任务 1
1.2.1 创建一个定时器任务 1
1.2.2 创建一个调度定时器 2
1.2.3 启动定时器 2
1.3 使用QUARTZ调度器 3
1.3.1 创建一个Quartz工作 3
1.3.2 调度工作 4
1.3.3 启动工作 5
1.4 按调度计划调度方法 5
1.4.1 MethodInvokingTimerTaskFactoryBean实现Timer Task 5
1.4.2 MethodInvokingJobDetailFactoryBean实现Quartz 6




1 调度任务
在web应用系统中,我们有时候会需要某些事件的发生由系统来引起和完成,而不是所有事件都由用户的动作来引起的。即使应用系统的很多功能都是通过用户的行为来引起的,但有些时候,系统需要根据某些任务调度规划来发起一些事件并完成它。

1.1 实现任务调度的背景
我在做一个ITSM(IT服务管理系统)的时候,需要完成一个功能:每天服务员责任任务处理时间只剩1/3的时候,需要邮件提醒服务员及时处理该任务。在该系统中我使用了SSH框架,对于该任务调度我采用了Spring的调度任务来实现。

1.2 使用Java Timer调度任务
从Java1.3开始,Java SDK就通过java.util.Timer类提供了基本的调度功能。这个类允许你调度一个任务(通过java.util.TimerTask子类定义)按任意的周期运行。
Spring通过TimerFactoryBean向应用程序上下文提供了对java Timer的支持,TimerFactoryBean是一个Spring工厂类,用于在应用程序上下文中生存Java Timer。
Spring中使用Java Timer调度任务的实现:

1.2.1 创建一个定时器任务
创建java Timer定时器任务需要继承java.util.TimerTask.
public class DailyMailTask extends TimerTask{

	private MailTaskService mailTaskService;
	@Override
	public void run() {
		mailTaskService.sendMailTask();
	}

	public MailTaskService getMailTaskService() {
		return mailTaskService;
	}
	public void setMailTaskService(MailTaskService mailTaskService) {
		this.mailTaskService = mailTaskService;
	}
}

Run方法为任务运行时调度执行的方法。
<!--定时器任务-->
<bean id="dailyMailTask" class="bgi.itsm.service.impl.DailyMailTaskImpl">
	<property name="mailTaskService" ref="mailTaskService"></property>
</bean>

1.2.2 创建一个调度定时器
Spring的ScheduledTimerTask定义了一个定时器任务的运行周期和延迟启动定时器。
<!-- 调度定时器任务 -->
	<bean id="scheduledMailTimerTask " class="org.springframework.scheduling.timer.ScheduledTimerTask">
		<property name="timerTask">
			<ref bean=”dailyMailTask "/>
		</property>
		<property name="delay">
			<value>6000</value>
		</property>
		<property name="period">
			<value>600000</value>
		</property>
	</bean>

属性timerTask告诉ScheduledTimerTask运行哪个TimerTask。再次,该属性装配了指向scheduledMailTimerTask的一个引用,它就是DailyMailTask。属性period告诉ScheduledTimerTask以怎样的频度调用TimerTask的run()方法。该属性以毫秒作为单位,它被设置为600000,指定这个任务应该每10分钟运行一次。属性delay允许你指定当任务第一次运行之前应该等待多久。在此指定dailyMailTask的第一次运行相对于应用程序的启动时间延迟6秒钟。

1.2.3 启动定时器
Spring的TimerFactoryBean负责启动定时任务。
<!-- 启动定时器 -->
	<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
		<property name="scheduledTimerTasks">
			<list>
				<ref bean=" scheduledMailTimerTask"/>
			</list>
		</property>
	</bean>

属性scheduledTimerTasks要求一个需要启动的定时器任务的列表。在此只包含一个指向scheduledMailTimerTask的引用。

1.3 使用Quartz调度器
Java Timer只能指定任务执行的频度,但无法精确指定它何时运行,这是它的一个局限性。要想精确指定任务的启动时间,就需要使用Quartz调度器。
Quartz调度任务为我们调度工作提供了更丰富的支持,Quartz调度器不仅可以定义每隔多少毫秒执行一个工作,还允许你调度一个工作在某个特定的时间或日期执行。
Spring中使用Quartz调度任务的实现:

1.3.1 创建一个Quartz工作
创建Quartz定时器任务需要继承Spring的QuartzJobBean.

public class DailyMailJob extends QuartzJobBean{

	private MailTaskService mailTaskService;
	@Override
	protected void executeInternal(JobExecutionContext jobContext)
			throws JobExecutionException {
		mailTaskService.sendMailTask();
	}

	public MailTaskService getMailTaskService() {
		return mailTaskService;
	}
	public void setMailTaskService(MailTaskService mailTaskService) {
		this.mailTaskService = mailTaskService;
	}
}


<!-- 声明邮件工作  -->
	<bean id="quartzMailJob" class="org.springframework.scheduling.quartz.JobDetailBean">
		<property name="jobClass">
			<value> bgi.itsm.action.DailyMailJob </value>
		</property>
		<property name="jobDataAsMap">
			<map>
				<entry key=" mailTaskService">
					<ref bean="mailTaskService"/>
				</entry>
			</map>
		</property>
	</bean>

JobDetailBean是Quartz的org.quartz.JobDetail的子类,它要求通过jobClass属性来设置一个job的实现。使用JobDetailBean的另一个特别之处是DailyMailJob的mailTaskService属性是间接设置的,通过jobDataAsMap来接受一个map(包含mailTaskService)注入DailyMailJob的mailTaskService属性。

1.3.2 调度工作
Spring提供了两个触发器SimpleTriggerBean和CronTriggerBean。
SimpleTriggerBean与scheduledTimerTasks类似。指定工作的执行频度,模仿scheduledTimerTasks配置。
<!-- 定时调度simple quartz工作  -->
	<bean id="simpleQuartzMailJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
		<property name="jobDetail">
			<ref bean="quartzMailJob"/>
		</property>
		<property name="startDelay">
			<value>6000</value>
		</property>
		<property name="repeatInterval">
			<value>600000</value>
		</property>
	</bean>  

属性jobDetail装配了将要被调度的工作,属性repeatInterval告诉触发器SimpleTrigerBean以怎样的频度运行这个工作(以毫秒为单位)。这里我们设置了600000毫秒,指定这个工作每隔10分钟运行一次。属性startDelay可以选择来设置延迟启动工作的第一次执行时间。这里我们设置了6000毫秒,推迟6秒执行该工作。
CronTriggerBean可以更精确地调度工作,我们可以使用CronTriggerBean来调度一个cron任务,CronTriggerBean是Quartz Trigger的另一个spring的子类,这个类允许你更精确地控制任务的运行时间和日期。类似Unix的cron。
<!—调度cron工作-->
	<bean id="cronQuartzMailJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<ref bean="quartzMailJob"/>
		</property>
		<property name="cronExpression">
			<value>0 30 2 * * ?</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)。
每一个元素都可以显式地规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素互斥,应该通过设置一个问号(?)来表明你不想设置的那个字段。我们在此定义该任务在每天凌晨两点半开始启动。

1.3.3 启动工作
Spring通过TimerFactoryBean负责启动定时工作。
<!—启动工作-->
	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
<ref bean="simpleQuartzMailJobTrigger "/>
				<ref bean="cronQuartzMailJobTrigger"/>
			</list>
		</property>
	</bean>

属性triggers接受一组触发器,在此只装配包含simpleQuartzMailJobTrigger b和cronQuartzMailJobTrigger的一个引用列表。

1.4 按调度计划调度方法
在上面Timer Task和Quartz的调度任务实现中,我们都要需要实现一个TimerTask和QuartzJobBean的子类,才能定义调度任务。
Spring还提供了一种不用实现一个TimerTask和QuartzJobBean的子类就可以调度任务类的方法。要达到这一目的可以通过Spring提供的MethodInvokingTimerTaskFactoryBean和MethodInvokingJobDetailFactoryBean来分别支持Timer Task和Quartz的任务调度实现。

1.4.1 MethodInvokingTimerTaskFactoryBean实现Timer Task
要通过MethodInvokingTimerTaskFactoryBean实现Timer Task的任务调度,我们可以将1.2.1中创建一个任务调度换成下面配置:
<!--定时器任务-->
<bean id="dailyMailTask" class="org.springframework.scheduling.timer.MehtodInvokingTimerTaskFactoryBean">
	<property name="targetObject" ref="mailTaskService"></property>
	<property name="targetMehtod ref="sendMialTask"></property>
</bean>

MethodInvokingTimerTaskFactoryBean 在幕后创建了一个TimerTask来对targetObject属性指定的对象调用targetMehod属性指定的方法。

1.4.2 MethodInvokingJobDetailFactoryBean实现Quartz
要通过MethodInvokingJobDetailFactoryBean实现Quartz的工作调度,我们可以将1.3.1中创建一个工作调度换成下面配置:
<!--定时器任务-->
<bean id="dailyMailJob" class="org.springframework.scheduling.Quartz. MethodInvokingJobDetailFactoryBean">
	<property name="targetObject" ref="mailTaskService"></property>
	<property name="targetMehtod ref="sendMialTask"></property>
</bean>

MethodInvokingJobDetailFactoryBean 在幕后创建了一个Quartz JobDetail来对targetObject属性指定的对象调用targetMehod属性指定的方法。
通过这种方式我们可以实现对某个类的某个方法进行调度,从而实现调度任务的功能。



-------------------------------------------------

参考《spring in action》

猜你喜欢

转载自xmong.iteye.com/blog/1296584