`
chorpin
  • 浏览: 132161 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring使用Quartz调度器 实现时间点任务(Spring in Action中文版)

    博客分类:
  • SSH
阅读更多
7.3.2  使用Quartz调度器
Quartz调度器为调度工作提供了更丰富的支持。和Java定时器一样,可以使用Quartz来每隔多少毫秒执行一个工作。但Quartz比Java Timer更先进之处在于它允许你调度一个工作在某个特定的时间或日期执行。

关于Quartz的更多信息,可以访问Quartz位于http://www.opensymphony.com/quartz的主页。

让我们从定义发送报表邮件的工作开始使用Quartz:

创建一个工作
定义Quartz工作的第一步是创建一个类来定义工作。要做到这一点,你需要从Spring的QuartzJobBean中派生子类,如程序清单7.3所示:

 程序清单7.3  定义一个Quartz工作
  public class EmailReportJob extends QuartzJobBean {
    public EmailReportJob() {}
    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()方法定义了当预定的时刻来临时应该执行哪些动作。在这里,正如EmailReportTask,你只是简单地调用了courseService属性的sendCourseEnrollmentReport()方法。

在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>

值得注意的是,在这里你并没有直接声明一个EmailReportJob Bean,而是声明了一个JobDetailBean。这是使用Quartz时的一个特点。JobDetailBean是Quartz的org.quartz.JobDetail的子类,它要求通过jobClass属性来设置一个Job对象。

使用Quartz的JobDetail中的另一个特别之处是EmailReportJob的courseService属性是间接设置的。JobDetail的jobDataAsMap属性接受一个java.util.Map,其中包含了需要设置给jobClass的各种属性。在这里,这个map包含了一个指向courseService Bean的引用,它的键值为courseService。当JobDetailBean实例化时,它会将courseService Bean注入到EmailReportJob的courseService属性中。

调度工作
现在工作已经被定义好了,接下来你需要调度这个工作。Quartz的org.quartz.Trigger类描述了何时及以怎样的频度运行一个Quartz工作。Spring提供了两个触发器,SimpleTriggerBean和CronTriggerBean。你应该使用哪个触发器?让我们分别考察一下这两个触发器,首先从SimpleTriggerBean开始。

SimpleTriggerBean与ScheduledTimerTask类似。你可以用它来指定一个工作应该以怎样的频度运行,以及(可选地)在第一次运行工作之前应该等待多久。例如,要调度报表工作每24小时运行一次,第一次在1小时之后开始运行,可以按照以下方式进行声明:

  <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>
  </bean>

属性jobDetail装配了将要被调度的工作,在这个例子中是reportJob Bean。属性repeatInterval告诉触发器以怎样的频度运行这个工作(以毫秒作为单位)。这里,我们设置它为86400000,因此每隔24小时它会被触发一次。你也可以选择设置startDelay属性来延迟工作的第一次执行。我们设置它为3600000,因此在第一次触发之前它会等待1小时。

调度一个cron工作
尽管你可能认为SimpleTriggerBean适用于大多数应用,但它仍然不能满足发送注册报表邮件的需求。正如ScheduledTimerTask,你只能指定工作执行的频度,而不能准确指定它于何时运行。因此,你无法使用SimpleTriggerBean在每天早晨6:00给课程主任发送注册报表邮件。

然而,CronTriggerBean允许你更精确地控制任务的运行时间。如果你对Unix的cron工具很熟悉,则会觉得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属性告诉触发器调度哪个工作。这里我们又一次装配了一个reportJob Bean。属性cronExpression告诉触发器何时触发。如果你不熟悉cron,这个属性可能看上去有点神秘,因此让我们进一步考察一下这个属性。

一个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)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素是互斥的,因此应该通过设置一个问号(?)来表明你不想设置的那个字段。表7.1中显示了一些cron表达式的例子和它们的意义:

表7.1                                            一些cron表达式的例子

表  达  式
意    义

0 0 10,14,16 * * ?
每天上午10点,下午2点和下午4点
0 0,15,30,45 * 1-10 * ?
每月前10天每隔15分钟
30 0 0 1 1 ? 2012
在2012年1月1日午夜过30秒时
0 0 8-5 ? * MON-FRI
每个工作日的工作时间

对于cronReportTrigger,我们设置cronExpression为0 0 6 * * ?可以把它读作“在任何月份任何日期(不管是星期几)的6时0分0秒执行触发器。”换句话说,这个触发器会在每天早晨6:00执行。
使用CronTriggerBean完全能够满足课程主任的期望了。现在剩下要做的只是启动这个工作了。
启动工作
Spring的SchedulerFactoryBean是Quartz中与TimerFactoryBean等价的类。按照如下方式在Spring配置文件中声明它:
  <bean class="org.springframework.scheduling.
         quartz.SchedulerFactoryBean">
    <property name="triggers">
      <list>
        <ref bean="cronReportTrigger"/>
      </list>
    </property>
  </bean>

属性triggers接受一组触发器。由于目前只有一个触发器,因此只需简单地装配一个包含cronReportTrigger Bean的一个引用的列表即可。
现在,你已经实现了调度发送注册报表邮件的需求。但在这个过程中,你做了一些额外的工作。在开始新的话题之前,首先让我们看一下如何通过更简单一些的方式调度报表邮件。

示例配置:
<beans>
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!--ref local="SocketJobTrigger"/>
                <ref local="RouteJobTrigger"/-->
</list>
</property>
</bean>
<!---->
<bean id="SocketJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<ref bean="SocketJobDetail"/>
</property>
<property name="startDelay">    
    <value>10000</value>
  </property>
  <property name="repeatInterval">
    <!-- repeat every 2 minutes -->
    <value>120000</value>
  </property>
</bean>
<bean id="SocketJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref local="quartzManager"/>
</property>
<property name="targetMethod">
<value>useQuartz</value>
</property>
</bean>

<bean id="socketManager" class="com.lxh.bean.quartzManager">
</bean>
<!---->
<bean id="RouteJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<ref bean="RouteJobDetail"/>
</property>
<property name="startDelay">    
    <value>30000</value>
  </property>
  <property name="repeatInterval">
    <value>30000</value>
  </property>
</bean>
<bean id="RouteJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref local="otherManager"/>
</property>
<property name="targetMethod">
<value>otherQuartz</value>
</property>
</bean>

<bean id="routeManager" class="com.lxh.job.otherManager">
</bean>
</beans>
2
0
分享到:
评论
2 楼 chorpin 2008-09-25  
两次任务之间是不同的线程吧,重复有关系吗?
至于你说的如果不把时间间隔调大,我也没有好的办法,期待高人出现
1 楼 huajz 2008-07-21  
 
我可以问一下吗?如果我的一个任务运行所需要的时间是30秒。但是我设了让他每10秒运行一次。这样的话就是每10秒运行一次任务。这样任务就重叠了。请问lz, 除了将每次运行的时间调大,还有什么办法可以让这些任务不重叠。是不是有什么参数可以设置的?

相关推荐

    SPRING in action(第三版中文版).pdf or 英文版

    《SPRING in Action》是Spring框架的一本权威指南,它为读者提供了全面深入的Spring框架知识。这本书的第三版详细介绍了Spring 3版本,涵盖了从基础到高级的各个方面,包括依赖注入、AOP(面向切面编程)、数据访问...

    quartz.*整合struts2、spring一个的demo

    通过Struts2的拦截器和结果类型,你可以将用户界面的交互转换为对Quartz调度器的操作。 Spring和Struts2的结合通常借助Spring-Struts2插件来完成,它可以使得Spring管理的Bean能够作为Struts2的Action类,使得...

    spring in action中文版

    《Spring in Action》是一本深度剖析Spring...总的来说,《Spring in Action中文版》全面覆盖了Spring框架的主要特性和用法,无论你是初学者还是经验丰富的开发者,都能从中受益匪浅,提升Spring应用开发的技能和效率。

    Spring in Action(第二版 中文高清版).part2

    12.3.2 使用Quartz调度器 12.3.3 按调度计划调用方法 12.4 使用JMX管理Spring Bean 12.4.1 将Spring Bean输出为MBean 12.4.2 远程访问MBean 12.4.3 处理通知 12.5 小结 第三部分 Spring客户端 第13章 处理...

    Spring in Action(第2版)中文版

    12.3.2使用quartz调度器 12.3.3按调度计划调用方法 12.4使用jmx管理springbean 12.4.1将springbean输出为mbean 12.4.2远程访问mbean 12.4.3处理通知 12.5小结 第三部分spring客户端 第13章处理web请求 13.1...

    Quartz定时调度

    1. `&lt;bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"&gt;` 这是启动Quartz调度器的bean。SchedulerFactoryBean会创建一个Scheduler实例,它是Quartz的核心,负责管理所有的作业和触发器。 ...

    Spring in Action(第二版 中文高清版).part1

    12.3.2 使用Quartz调度器 12.3.3 按调度计划调用方法 12.4 使用JMX管理Spring Bean 12.4.1 将Spring Bean输出为MBean 12.4.2 远程访问MBean 12.4.3 处理通知 12.5 小结 第三部分 Spring客户端 第13章 处理...

    Spring in Action, Third Edition 文字版

    Spring的集成能力也是其一大亮点,例如集成Quartz调度器、电子邮件服务等,这些都会在书中有所介绍。 总之,《Spring in Action, Third Edition》结合了理论与实践,是一本全面了解和掌握Spring框架的宝贵资源。...

    spring的定时任务的配置

    Spring 框架提供了强大的任务调度功能,使得开发者能够轻松地在应用中实现定时任务。本篇文章将详细探讨如何在 Spring 中配置定时任务,并通过具体的示例代码进行说明。 #### 二、Spring 定时任务配置原理 在 ...

    SPRING 定时器的使用

    在Spring框架中,实现定时任务有两种主流方式:使用`java.util.Timer`类或集成第三方库如Quartz。这两种方法各有优势: - **Java Timer**:简单易用,适合简单的定时任务需求。 - **Quartz**:功能强大且灵活,支持...

    ssh2+quartz整合

    5. 启动Scheduler:在应用程序启动时,通过Spring的SchedulerFactoryBean启动Quartz调度器。 在"testssh2"这个文件中,可能包含了整合SSH2和Quartz的示例代码、配置文件和其他相关资源。通过分析和运行这些文件,...

    java定时任务的实现方式

    本文将详细介绍两种常用的Java定时任务实现方式:Timer类和Spring框架的Quartz调度器。 首先,第一种方式是使用Java内置的`Timer`类。`Timer`类提供了定时任务调度的功能,可以按照预设的时间间隔执行任务。在提供...

    Spring定时器.pdf

    Spring 框架提供了多种方式来实现定时任务,其中一种常见的方法是使用 Quartz 作为定时任务的调度器。Quartz 是一个开源的作业调度工具,能够运行在独立的线程中,并能触发任务在指定的时间执行。 在本文档中,我们...

    spring定时任务

    ### Spring 定时任务知识点详解 #### 一、Spring与Quartz概述 Spring框架作为一款广泛使用的Java开发框架,提供了丰富的功能支持,其中包括对定时任务的支持。为了更好地管理定时任务,Spring通过集成Quartz插件来...

    Manning.Spring.in.Action.2nd.Edition.Aug.2007

    5. **Spring的集成能力**:Spring可以与许多其他流行的技术和框架无缝集成,如Hibernate(对象关系映射)、Struts(MVC框架)、Quartz(任务调度)、JMS(消息传递)等。 6. **测试支持**:Spring提供了丰富的测试...

    Spring定时器配置详解

    这个特性主要依赖于Quartz库,一个流行的Java作业调度框架,但Spring提供了更简单的API来集成和配置定时任务。 1. 创建定时任务类 在Spring中,你需要创建一个实现特定接口或包含公共无参数方法的类来定义定时任务...

    在Java的Spring框架中配置Quartz的教程

    在Spring框架中集成Quartz能够让我们通过Spring的依赖注入和声明式事务管理等特性来管理任务调度。 在Spring中配置Quartz时,需要关注以下几个方面: 1. 引入Quartz所需的JAR包。这些JAR包是Spring框架的一部分,...

    java毕设之基于SSH的任务调度系统的设计与实现

    《基于SSH的任务调度系统的设计与实现》是Java毕业设计中的一个重要课题,主要涉及SSH(Struts2、Spring、Hibernate)框架的应用以及任务调度系统的构建。本项目提供了完整的前后端源码,确保项目能够正常运行,并...

    SSH框架+Quartz集群

    在RABC权限管理中,Struts可以通过拦截器或Action配置来实现权限校验,确保用户只能访问其角色允许的资源。 Hibernate作为ORM(Object-Relational Mapping)工具,负责数据库的操作。它简化了数据库访问,通过映射...

    JAVA定时器JAVA定时器.pdf

    JAVA定时器是一种基于Quartz框架的任务调度器,用于在指定的时间执行特定的任务。在 Spring 框架中,JAVA定时器可以与Quartz框架集成,实现自动执行任务的功能。 1. JAVA定时器的基本概念 JAVA定时器是基于Quartz...

Global site tag (gtag.js) - Google Analytics