首页 » 网上的 » 正文

Spring调度任务学习

 

并非应用系统中发生的所有事情都是由用户的动作引起的。有时候,系统自己也会发起一个动作。比方说最近的项目中,要求系统每到晚上12点就检查数据库中所有订单的状态,将所有草稿状态的订单的状态修改为超时取消。这个时候我们就可以利用Spring为我们提供的任务调度功能了。

 

今天自己试用了一把Spring的任务调度,我的逻辑很简单,让后台每过一分钟就打印一句“This is My Schedule Test”。下面开始吧!

 

一.创建一个工作类

 

首先我们要创建一个类来定义工作。要做到这点,我们需要从Spring的QuartzJobBean中派生子类,如下所示:

QuartzJobBean.java:

import org.springframework.scheduling.quartz.QuartzJobBean;

import test.service.IScheduleDetail;

/**

 * @author CMTobby 2007-9-21

*/

public class PrintMessageJob extends QuartzJobBean {

    private IScheduleDetail scheduleDetail;

    private String msg;

 

    @Override

    protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {

       scheduleDetail.printDetail();

    }

    public IScheduleDetail getScheduleDetail() {

       return scheduleDetail;

    }

    public void setScheduleDetail(IScheduleDetail scheduleDetail) {

       this.scheduleDetail = scheduleDetail;

    }

}

 

    这里我们还需要下载一个Quartz的包,最新的是quartz-1.6.0.jar

 

尽管这个任务掉多执行的操作很简单,但是为了体现分层思想,我还是将这个操作写在了service层中。代码如下所示:

 

IScheduleDetail.java:

 

package test.service;

public interface IScheduleDetail {

    public void printDetail();

}

 

ScheduleDetailImpl.java:

package test.service.impl;

import test.service.IScheduleDetail;

/**

 * @author zhukai 2007-9-21

 *

 */

public class ScheduleDetailImpl implements IScheduleDetail {

    public void printDetail() {

        System.out.println("这个是我们要调度的动作");

    }

}

 

这样的话我们只需在工作类中简单的调用服务类即可,工作类只负责被调度时调用具体的方法,在服务类中我们还可以扩展别的操作。注意,executeInternal方法继承自QuartzJobBean,我们必须实现它,当任务被调度的时候就是执行这个方法。

 

二.让Spring知道你的工作类

 

工作类定义好了如何让Spring知道呢?我们只需要在Spring中配置文件中声明即可,如下所示:

<!—- 配置服务 –>

<bean id="scheduleDetail"   class="test.service.impl.ScheduleDetailImpl"></bean>

    <!– 创建一个工作 –>

    <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">

<!– 指定要调度的工作,需实现Job接口,通常是继承QuartzJobBean抽象类 –>

        <property name="jobClass">

            <value>test.web.PrintMessageJob</value>

        </property>

        <property name="jobDataAsMap">

            <map>

                <entry key="scheduleDetail">

                    <ref bean="scheduleDetail"/>

                </entry>

            </map>

        </property>

</bean>

这里我们使用了JobDetailBean类,它的jobClass用于指定工作类,这里类通常要实现org.quartz.Job接口。jobDataAsMap属性用来给jobClass所指定类的属性注入值,例如上例中我们给PrintMessageJob的scheduleDetail属性注入了一个已声明好的bean。

 

三.调度工作

现在我们需要来对工作进行调度了,譬如说指定何时开始以怎样的频率来执行这个任务。本例中我们是指定每分钟打印一条语句。我们的调度配置如下所示:

<!– 调度一个工作 –>

    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">

        <property name="jobDetail">

            <ref bean="jobDetail"/>

        </property>

        <!– 工作执行的频率,以毫秒为单位 –>

        <property name="repeatInterval">

            <value>60000</value><!—- 一分钟打印一次 –>

        </property>

</bean>

 

四.启动工作

一切准备就绪之后,我们就要启动我们的工作调度任务了,配置如下:

    <!– 启动工作 –>

    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

        <property name="triggers"><!– 接受一组触发器 –>

            <list>

                <ref bean="simpleTrigger"/>

            </list>

        </property>

</bean>

 

OK,现在我们服务器(我的Spring是和Struts集成在一起的),就会发现每过一分钟,后台就会打印出一句:这个是我们要调度的动作,是不是很简单。

 

最后有一点要说明的,这个问题浪费了很多时间:我在启动服务的时候总是提示我不能创建名字为jobDetail的bean,然后提示NoSuchMethodError错误,如下所示:org.apache.commons.collections.SetUtils.orderedSet(Ljava/util/Set;)为此我检查了我的配置和程序不下几十次,还上网找了很多资料,最后导致这个错误的原因很简单:我用的commons-collections-2.1.1.jar包太老了,我下载最新的commons-collections-3.2.jar包放进去之后就一切OK了,这个错误BT吧。

 

 

本文来自:http://blog.csdn.net/CMTobby/archive/2007/09/21/1795257.aspx