做开发的时候很多时候面临着一个问题,那就是定时任务的问题,比如我之前做的搜索引擎系统,新闻模块每小时更新一次,视频每2小时更新一次,汽车频道没一周更新一次;显然这种更新不应该由人工来完成,一个是工作量非常大,二个是显得很没有技术含量;在这方面spring提供了ScheduledTimerTask,就是通常所说的任务了;把配置好的任务(ScheduledTimerTask)塞到调度器TimerFactoryBean里面就可以了,当然了TimerFactoryBean可以同时执行多个任务;看了一下spring的源代码,ScheduledTimerTask和TimerFactoryBean也很简单,ScheduledTimerTask就是对java.util包下的TimerTask做了简单的封装,而TimerFactoryBean也是对java.util包下的Timer包装一下,现在把源代码放上来看一下:
package org.springframework.scheduling.timer;
import java.util.TimerTask;
public class ScheduledTimerTask
{
private TimerTask timerTask;
private long delay = 0L;
private long period = 0L;
private boolean fixedRate = false;
public ScheduledTimerTask(TimerTask timerTask)
{
this.timerTask = timerTask;
}
public ScheduledTimerTask(TimerTask timerTask, long delay)
{
this.timerTask = timerTask;
this.delay = delay;
}
public ScheduledTimerTask(TimerTask timerTask, long delay, long period, boolean fixedRate)
{
this.timerTask = timerTask;
this.delay = delay;
this.period = period;
this.fixedRate = fixedRate;
}
public void setTimerTask(TimerTask timerTask)
{
this.timerTask = timerTask;
}
public TimerTask getTimerTask()
{
return this.timerTask;
}
public void setDelay(long delay)
{
this.delay = delay;
}
public long getDelay()
{
return this.delay;
}
public void setPeriod(long period)
{
this.period = period;
}
public long getPeriod()
{
return this.period;
}
public void setFixedRate(boolean fixedRate)
{
this.fixedRate = fixedRate;
}
public boolean isFixedRate()
{
return this.fixedRate;
}
}
以下是TimerFactoryBean的源代码:
package org.springframework.scheduling.timer;
import java.util.Timer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
public class TimerFactoryBean
implements FactoryBean, InitializingBean, DisposableBean
{
protected final Log logger;
private ScheduledTimerTask[] scheduledTimerTasks;
private boolean daemon;
private Timer timer;
public TimerFactoryBean()
{
this.logger = LogFactory.getLog(super.getClass());
this.daemon = true;
}
public void setScheduledTimerTasks(ScheduledTimerTask[] scheduledTimerTasks)
{
this.scheduledTimerTasks = scheduledTimerTasks;
}
public void setDaemon(boolean daemon)
{
this.daemon = daemon;
}
public void afterPropertiesSet() {
this.logger.info("Initializing Timer");
this.timer = createTimer(this.daemon);
for (int i = 0; i < this.scheduledTimerTasks.length; ++i) {
ScheduledTimerTask scheduledTask = this.scheduledTimerTasks[i];
if (scheduledTask.getPeriod() > 0L)
{
if (scheduledTask.isFixedRate()) {
this.timer.scheduleAtFixedRate(scheduledTask.getTimerTask(), scheduledTask.getDelay(), scheduledTask.getPeriod());
}
else
{
this.timer.schedule(scheduledTask.getTimerTask(), scheduledTask.getDelay(), scheduledTask.getPeriod());
}
}
else
{
this.timer.schedule(scheduledTask.getTimerTask(), scheduledTask.getDelay());
}
}
}
protected Timer createTimer(boolean daemon)
{
return new Timer(daemon);
}
public Object getObject()
{
return this.timer;
}
public Class getObjectType() {
return Timer.class;
}
public boolean isSingleton() {
return true;
}
public void destroy()
{
this.logger.info("Cancelling Timer");
this.timer.cancel();
}
}
最后做一个小demo
步骤:
1开发任务类,也就是继承了java.util.TimerTask的类,并写好该类的run 方法,run方法里面就是要执行的业务逻辑
2 写好spring的application配置文件
package task;
import java.util.Date;
import java.util.TimerTask;
public class NewsTimeTask extends TimerTask{
private int i=0;
public void run() {
System.out.println("开始进行第--"+(++i)+"--次car---新闻的搜集--"+this.getClass().getName()+"/////////"+new Date());
}
}
package task;
import java.util.Date;
import java.util.TimerTask;
public class VideoTimerTask extends TimerTask {
private int i=0;
public void run() {
System.out.println("开始进行第--"+(++i)+"--次car---视频的搜集--"+this.getClass().getName()+"/////////"+new Date());
}
}
package task;
import java.util.Date;
import java.util.TimerTask;
public class CarTimerTask extends TimerTask{
private int i=0;
public void run(){
System.out.println("开始进行第--"+(++i)+"--次car---汽车的搜集--"+this.getClass().getName()+"/////////"+new Date());
}
}
applicationContext.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ":/spring-beans.dtd">
-->
<beans>
<bean id="newsTask" class="task.NewsTimeTask"></bean>
<bean id="videoTask" class="task.VideoTimerTask"></bean>
<bean id="carTask" class="task.CarTimerTask"></bean>
<bean id="newsScheduledTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<!-- 系统启动后60秒开始执行 -->
<property name="delay" value="60000"></property>
<!-- 每60秒执行一次 -->
<property name="period" value="60000"></property>
<property name="timerTask" ref="newsTask"></property>
</bean>
<bean id="videoScheduledTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay" value="60000"></property>
<property name="period" value="180000"></property>
<property name="timerTask" ref="videoTask"></property>
</bean>
<bean id="carScheduledTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay" value="60000"></property>
<property name="period" value="300000"></property>
<property name="timerTask" ref="carTask"></property>
</bean>
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="newsScheduledTask"/>
<ref bean="videoScheduledTask"/>
<ref bean="carScheduledTask"/>
</list>
</property>
</bean>
</beans>
只要启动spring之后任务就自动执行了,不在用做任务其他额外的工作!
程序的输出如下:
开始进行第--1--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:13:27 CST 2009
开始进行第--1--次car---视频的搜集--task.VideoTimerTask/////////Wed Jul 29 10:13:27 CST 2009
开始进行第--1--次car---汽车的搜集--task.CarTimerTask/////////Wed Jul 29 10:13:27 CST 2009
开始进行第--2--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:14:27 CST 2009
开始进行第--3--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:15:27 CST 2009
开始进行第--4--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:16:27 CST 2009
开始进行第--2--次car---视频的搜集--task.VideoTimerTask/////////Wed Jul 29 10:16:27 CST 2009
开始进行第--5--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:17:27 CST 2009
开始进行第--6--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:18:27 CST 2009
开始进行第--2--次car---汽车的搜集--task.CarTimerTask/////////Wed Jul 29 10:18:27 CST 2009
开始进行第--7--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:19:27 CST 2009
开始进行第--3--次car---视频的搜集--task.VideoTimerTask/////////Wed Jul 29 10:19:27 CST 2009
开始进行第--8--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:20:27 CST 2009
开始进行第--9--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:21:27 CST 2009
开始进行第--10--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:22:27 CST 2009
开始进行第--4--次car---视频的搜集--task.VideoTimerTask/////////Wed Jul 29 10:22:27 CST 2009
开始进行第--3--次car---汽车的搜集--task.CarTimerTask/////////Wed Jul 29 10:23:27 CST 2009
开始进行第--11--次car---新闻的搜集--task.NewsTimeTask/////////Wed Jul 29 10:23:27 CST 2009