在Spring中使用 Java Timer 调度任务

从Java 1.3开始,Java SDK就通过java.util.Timer类提供了基本的调度功能。这个类允许你调度一个任务(通过java.util.TimerTask子类定义)按任意周期运行。

创建一个定时器任务

使用Java Timer来调度发送注册报表邮件的第一步是从java.util.TimerTask中派生出邮件任务,如以下程序所示。

程序:一个用于发送注册报表邮件的定时器任务

    public class EmailReportTask extends TimerTask {  
        public EmailReportTask() {}  
        public void run() {  
            courseService.sendCourseEnrollmentReport();  
        }  
        private CourseService courseService;  
        public void setCourseService(CourseService courseService) {  
            this.courseService = courseService;   
        }  
    }  

run()方法定义了当任务运行时该做什么。在上面的例子中,它调用CourseServicesendCourseEnrollmentReport()方法(见程序清单7.1)来发送注册报表邮件。CourseService是通过依赖注入方式提供给EmailReportTask的。
按以下方式在Spring配置文件中声明EmailReportTask

    <bean id="reportTimerTask" class="com.springinaction.training.schedule.EmailReportTask">  
        <property name="courseService">  
            <ref bean="courseService"/>  
        </property>  

    </bean>  

这个声明本身只是将EmailReportTask放到应用上下文中,并在courseService属性中装配courseService Bean。在你调度它之前,它不会做任何有用的事。

调度定时器任务

Spring的ScheduledTimerTask定义了一个定时器任务的运行周期。既然课程主任要求每天向她发送注册报表,你应该以如下方式装配一个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的一个引用,它就是EmailReportTask。属性period告诉ScheduledTimerTask以怎样的频度调用TimerTask的run()方法。这个属性以毫秒作为单位,它被设置为86400000,指定这个任务应该每24小时运行一次。

启动定时器

最后一步是启动定时器。Spring的TimerFactoryBean负责启动定时任务。按以下方式在Spring配置文件中声明它:

    <bean class="org.springframework.scheduling.timer.TimerFactoryBean">  
         <property name="scheduledTimerTasks">  
            <list>  
                <ref bean="scheduledReportTask"/>  
            </list>  
        </property>  
    </bean>  

属性scheduledTimerTasks要求一个需要启动的定时器任务的列表。既然你现在只有一个定时器任务,这个列表中只包含一个指向scheduledReportTask Bean的引用。

遗憾的是,即使这个任务已经能够每隔24小时运行一次了,在这里你无法指定它应该在一天中的哪个时间点执行。ScheduledTimerTask有一个delay属性,允许你指定当任务第一次运行之前应该等待多久。例如,要将EmailReportTask的第一次运行延迟1小时,可以按照以下方式进行配置:


    <bean class="org.springframework.scheduling.timer.TimerFactoryBean">  
         <property name="scheduledTimerTasks">  
            <list>  
                <ref bean="scheduledReportTask"/>  
            </list>  
        </property>  

        <!-- delay 属性指定其间隔时间 -->  
        <property name="delay">  
            <value>3600000</value>  
        </property>  
    </bean>  

即使使用deplay属性,EmailReportTask的第一次运行时间仍然是相对于应用程序的启动时间的。怎样才能做到如课程主任所要求的在每天早晨6:00发送邮件(而不是在早晨5:00启动应用程序)呢?
遗憾的是,这是Java Timer的一个局限性。你可以指定任务执行的频度,但你无法精确指定它何时运行。为了能够精确指定何时发送电子邮件,你需要使用Quartz调度器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值