`
newleague
  • 浏览: 1492698 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

spring提供的任务调度支持

阅读更多

Spring 中正确使用 Quartz CronExpression

     Quartz 作为企业级任务调度框架以其灵活的使用方式、强大的功能已经得到广泛应用,作为一向喜欢将业内流行的工具纳入支持的 Spring 自然已经内置 了对 Quartz 的支持,使得 Quartz 中最常使用的 SimpleTrigger CronTrigger 的使用得到了最大简化,分别对应 Spring org.springframework.scheduling.quartz.SimpleTriggerBean org.springframework.scheduling.quartz.CronTriggerBean ,这两个类用起来非常方便,其中 SimpleTrigger 更类似于 JDK 中的 Timer ,它只是简单的以某个时间间隔来执行某个任务而已,比较简陋,而 CronTrigger 功能则十 分强大,可以设定制定任务在任意指定时刻内调用,其使用 Unix 中的 Cron Expression 来制定调度策略,十分灵活,不过 Cron Expression 可能需要用点时间来学习,不过一旦掌握会觉得真的很不错,掌握了这两种 Trigger 基本上就可以应付实现大多数 J2EE 应用中的时 间任务调度服务了。

     下面举一个简单例子说明一下在 Spring1.2.5 中使用 Quartz1.5 的方式(所需要的包在 Spring1.2.5 的发行版中的 lib 目录下可以找到,将其拷贝到工程的类路径中)。

     首先建立两个要调度的任务,他们都必须继承自 org.springframework.scheduling.quartz.QuartzJobBean ,而业务逻辑都是放在 executeInternal 方法中,指定的任务逻辑实现之后,需要将其注入到一个 JobDetailBean 中, JobDetailBean 可以看作 为一个具体任务的设置它指定了要执行的任务和执行任务的时间策略, JobDetailBean 不用实现,只需要在 Spring 的配置文件中设置便可:

package com.peuo.albumSys.scheduling;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import org.apache.log4j.Logger;

import com.peuo.albumSys.business.IAlbumSysService;
import com.peuo.albumSys.domainobj.User;
import com.peuo.albumSys.domainobj.Album;

/**
*
在指定的时刻查询当前所有的用户,并显示其姓名。
* @author Shippo Field
*/
public class ScheduledQueryUsers extends QuartzJobBean {
     private static Logger log = Logger.getLogger(ScheduledQueryUsers.class);
    
     private IAlbumSysService service = null;

     /**
      * @param service
要设置的业务逻辑 Bean 实例,可以是已被纳入事务管理的某个 Bean ,这样以来 QuartzJobBean 内部逻辑也可以纳入事务管理。
      */
     public void setService(IAlbumSysService service) {
         this.service = service;
     }
    
     /*
(非 Javadoc
      * @see org.springframework.scheduling.quartz.QuartzJobBean#executeInternal(org.quartz.JobExecutionContext)
      */
     protected void executeInternal(JobExecutionContext ctx)
             throws JobExecutionException {
         log.debug("Now entering method executeInternal()...");
         List users = service.findAllUser();
         StringBuffer str = new StringBuffer();
         for(int i = 0; i < users.size(); i++){
             User user = (User)users.get(i);
             str.append("\nUser[" + i + "] = " + user.getUserName());
             Set albums = user.getAlbumSet();
             Iterator it = albums.iterator();
             str.append("(Albums:");
             while(it.hasNext()){
                 str.append(((Album)it.next()).getAlbumName()).append(";");
             }
         }
         log.debug(str.toString());
     }

}

  

package com.peuo.albumSys.scheduling;

import java.util.Date;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import org.springframework.scheduling.quartz.QuartzJobBean;

import org.apache.log4j.Logger;

import com.peuo.albumSys.business.IAlbumSysService;
import com.peuo.albumSys.domainobj.Album;
import com.peuo.albumSys.domainobj.Photo;

/**
*
本程序会在指定的时刻插入照片
* @author Field
*/
public class ScheduledAddPhoto extends QuartzJobBean {
     private static Logger log = Logger.getLogger(ScheduledAddPhoto.class);
    
     private IAlbumSysService service = null;
     private static int count = 0;
     /*
(非 Javadoc
      * @see org.springframework.scheduling.quartz.QuartzJobBean#executeInternal(org.quartz.JobExecutionContext)
      */
     protected void executeInternal(JobExecutionContext arg0)
             throws JobExecutionException {
         Date now = new Date(System.currentTimeMillis());
         Photo newPhoto = new Photo();
         newPhoto.setAlbum(new Album(new Integer(1)));
         newPhoto.setPhotoName( now.toString());
         newPhoto.setPhotoUrl("Photo url" + ++count);
         service.addPhoto(newPhoto);
         log.debug("New photo added : name =" + newPhoto.getPhotoName() +"; url = " + newPhoto.getPhotoUrl());
     }

     /**
      * @return
当前业务逻辑实例。
      */
     public IAlbumSysService getService() {
         return service;
     }
     /**
      * @param service
要设置的业务逻辑实例。
      */
     public void setService(IAlbumSysService service) {
         this.service = service;
     }
}
然后在Spring的配置文件中分别设置一个SimpleTriggerBeanCronTriggerBean来调用上面两个任务,配置如下:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "
http://www.springframework.org/dtd/spring-beans.dtd ">

<beans>

……………………………………………………………………………………………………

    <bean id="queryUserJob" class="org.springframework.scheduling.quartz.JobDetailBean">
     <property name="jobClass">
      <value>com.peuo.albumSys.scheduling.ScheduledQueryUsers</value>
     </property>
     <property name="jobDataAsMap">
      <map>
       <entry key="service">
        <ref local="albumSysService"/>
     </entry>
      </map>
     </property>

    </bean>
   
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
     <property name="jobDetail">
      <ref local="queryUserJob"/>
     </property>
     <property name="startDelay">
      <value>15000</value>
     </property>
     <property name="repeatInterval">
      <value>60000</value>
     </property>
     <property name="repeatCount">
      <value>-1</value>
     </property>
    </bean>
   
<bean id="addPhotoJob" class="org.springframework.scheduling.quartz.JobDetailBean">
   <property name="jobClass">
    <value>com.peuo.albumSys.scheduling.ScheduledAddPhoto</value>
   </property>
<property name="jobDataAsMap">
    <map>
     <entry key="service">
      <ref local="albumSysService" />
     </entry>
    </map>
   </property>
</bean>

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
   <property name="jobDetail">
    <ref local="addPhotoJob"/>
   </property>
   <property name="cronExpression">
    <value>0 20 19 * * ?</value>
   </property>
</bean>

    <bean id="sfb" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
     <property name="triggers">
      <list>
       <ref local="simpleTrigger"/>
     <ref local="cronTrigger"/>
      </list>
     </property>
    </bean>

  

上面红色标出的部分可以看出, Spring 对于将 QuartzJob 注入 JobDetailBean 的方式有点特殊,你需要将要注入给 QuartzJob 的某个属性注入到 JobDetailBean jobDataAsMap 中, 这不同于 Spring 平时直接对某个 Bean 的属性直接注入的方式,这主要是因为 Quartz 执行一个任务( JOB 或者叫作业)的时候会提供给任务一个 JobExecutionContext 的任务执行上下文,从这个上下文中可以获得 Job 的环境设置,具体的可以看一下 Quartz API 文档就明白 了,反正只要记住这里的注入方式比较特殊就行了。

以上配置文件分别设置了一个 SimpleTriggerBean CronTriggerBean ,前者将会在程序执行 15 秒之后开始不断以间隔一 分钟的方式不断查询当前用户信息并显示出来,后者则指定每天的 19 20 分执行向 ID 1 的用户的相册内添加一张照片的任务,其 Cron Expression 0 20 19 * * ?

从以上可以看出, Spring 大大简化了对 Quartz 任务时间调度框架的使用,将其完美的融合入了 Spring 提供的 IoC 容器,只是其注入方式需要注意,还有就是 Cron Expression 一定要掌握,这个是 Quartz 真正的强大之处。

  

网上似乎对 Cron 表达式的中文介绍相当少,我干脆就把 Quartz 中的 doc 翻译一下,各位需要的朋友可以快速了解一下大致用法:

一个 Cron- 表达式是一个由六至七个字段组成由空格分隔的字符串,其中 6 个字段是必须的而一个是可选的,如下:

字段名

  

允许的值

  

允许的特殊字符

  

0-59

  

, - * /

  

0-59

  

, - * /

小时

  

0-23

  

, - * /

  

1-31

  

, - * ? / L W C

  

1-12 or JAN-DEC

  

, - * /

周几

  

1-7 or SUN-SAT

  

, - * ? / L C #

( 可选字段 )

  

empty, 1970-2099

  

, - * /

'*' 字符可以用于所有字段,在 字段中设为 "*" 表示 " 每一分钟 " 的含义。

'?' 字符可以用在 周几 字段 . 它用来指定 ' 不明确的值 '. 这在你需要指定这两个字段中的某一个值而不是另外一个的时候会被用到。在后面的例子中可以看到其含义。

'-' 字符被用来指定一个值的范围,比如在 小时 字段中设为 "10-12" 表示 "10 点到 12 ".

',' 字符指定数个值。比如在 周几 字段中设为 "MON,WED,FRI" 表示 "the days Monday, Wednesday, and Friday".

'/' 字符用来指定一个值的的增加幅度 . 比如在 字段中设置为 "0/15" 表示 " 0, 15, 30, 45 " 。而 "5/15" 则表示 " 5, 20, 35, 50". '/' 前加 "*" 字符相当于指定从 0 秒开始 . 每个字段都有一系列可以开始或结束的数值。对于 字段来说,其数值范围为 0 59 ,对于 小时 字段来说其为 0 23, 对于 字段来说为 0 31, 而对于 字段来说为 1 12 "/" 字段仅仅只是帮助你在允许的数值范围内从开始 " n" 的值。 因此 对于 字段来说 "7/6" 只是表示 7 月被开启而不是 每六个月 ”, 请注意其中微妙的差别。

'L' 字符可用在 周几 这两个字段。它是 "last" 的缩写 , 但是在这两个字段中有不同的含义。例如 ,“ 字段中的 "L" 表示 " 一个月中的最后一天 " —— 对于一月就是 31 号对于二月来说就是 28 号(非闰年)。而在 周几 字段中 , 它简单的表示 "7" or "SAT" ,但是如果在 周几 字段中使用时跟在某个数字之后 , 它表示 " 该月最后一个星期 ×" —— 比如 "6L" 表示 " 该月最后一个周五 " 。当使用 'L' 选项时 , 指定确定的列表或者范围非常重要,否则你会被结果搞糊涂的。

'W' 可用于 字段。用来指定历给定日期最近的工作日 ( 周一到周五 ) 。比如你将 字段设为 "15W" ,意为 : " 离该月 15 号最近的工作日 " 。因此如果 15 号为周六,触发器会在 14 号即周五调用。如果 15 号为周日 , 触发器会在 16 号也就是周一触发。如果 15 号为周二 , 那么当天就会触发。然而如果你将 字段设为 "1W", 而一号又是周六 , 触发器会于下周一也就是当月的 3 号触发 , 因为它不会越过当月的值的范围边界。 'W' 字符只能用于 字段的值为单独的一天而不是一系列值的时候。

'L' 'W' 可以组合用于 字段表示为 'LW' ,意为 " 该月最后一个工作日 "

'#' 字符可用于 周几 字段。该字符表示 该月第几个周 ×” ,比如 "6#3" 表示该月第三个周五 ( 6 表示周五而 "#3" 该月第三个 ) 。再比如 : "2#1" = 表示该月第一个周一而 "4#5" = 该月第五个周三。注意如果你指定 "#5" 该月没有第五个 ×” ,该月是不会触发的。

'C' 字符可用于 周几 字段,它是 "calendar" 的缩写。 它表示为基于相关的日历所计算出的值(如果有的话)。如果没有关联的日历 , 那它等同于包含全部日历。 字段值为 "5C" 表示 " 日历中的第一天或者 5 号以后 " 周几 字段值为 "1C" 则表示 " 日历中的第一天或者周日以后 "

对于 月份 字段和 周几 字段来说合法的字符都不是大小写敏感的。

下面是一些完整的例子 :

表达式

  

含义

"0 0 12 * * ?"

  

每天中午十二点触发

"0 15 10 ? * *"

  

每天早上 10 15 触发

"0 15 10 * * ?"

  

每天早上 10 15 触发

"0 15 10 * * ? *"

  

每天早上 10 15 触发

"0 15 10 * * ? 2005"

  

2005 年的每天早上 10 15 触发

"0 * 14 * * ?"

  

每天从下午 2 点开始到 2 59 分每分钟一次触发

"0 0/5 14 * * ?"

  

每天从下午 2 点开始到 2 55 分结束每 5 分钟一次触发

"0 0/5 14,18 * * ?"

  

每天的下午 2 点至 2 55 6 点至 6 55 分两个时间段内每 5 分钟一次触发

"0 0-5 14 * * ?"

  

每天 14:00 14:05 每分钟一次触发

"0 10,44 14 ? 3 WED"

  

三月的每周三的 14 10 14 44 触发

"0 15 10 ? * MON-FRI"

  

每个周一、周二、周三、周四、周五的 10 15 触发

"0 15 10 15 * ?"

  

每月 15 号的 10 15 触发

"0 15 10 L * ?"

  

每月的最后一天的 10 15 触发

"0 15 10 ? * 6L"

  

每月最后一个周五的 10 15 触发

"0 15 10 ? * 6L"

  

每月最后一个周五的 10 15 触发

"0 15 10 ? * 6L 2002-2005"

  

2002 年至 2005 年的每月最后一个周五的 10 15 触发

"0 15 10 ? * 6#3"

  

每月的第三个周五的 10 15 触发

请注意 '?' '*' 周几 字段中的用法 !

分享到:
评论

相关推荐

    spring 任务调度

    通过深入学习Spring任务调度,开发者可以有效地管理和执行各种定时任务,提升系统的自动化水平。在实际项目中,可以根据需求的复杂程度选择使用Spring Task或是集成Quartz。同时,理解源码有助于我们更高效地利用...

    Spring实现任务调度

    然而,对于更复杂的任务调度需求,如复杂的调度策略、集群支持等,Spring还支持与Quartz Scheduler的集成。Quartz是一个功能丰富的开源任务调度库,提供了丰富的API和配置选项。要在Spring中使用Quartz,我们需要...

    Spring实现任务调度.rar

    除了内置的`TaskScheduler`,Spring还支持集成第三方任务调度库,如Quartz。Quartz是一个强大且功能丰富的作业调度框架,允许创建复杂的调度规则。在描述中提到的`quartz-all-1.6.1.jar`是Quartz库的旧版本,可能...

    spring分布式任务调度

    改分布式任务调度特性如下: 1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手; 2、动态:支持动态修改任务状态、暂停/恢复任务,以及终止运行中任务,即时生效; 3、调度中心HA(中心式):调度...

    Spring整合任务调度框架Quartz

    Spring 整合任务调度框架 Quartz 在软件开发中,任务调度框架是非常重要的一部分,它可以帮助开发者更好地管理和执行各种任务。在 Java 领域中,Quartz 是一个非常流行的任务调度框架,而 Spring 是一个非常流行的 ...

    spring任务调度(Quartz )

    Spring中的任务调度是实现应用程序自动化运行任务的重要工具,而Quartz是Java领域广泛使用的开源任务调度框架。在本文中,我们将深入探讨如何在Spring中集成Quartz进行任务调度,并通过一个简单的示例来理解其工作...

    spring quartz 任务调度

    Spring框架作为一个全面的企业级应用开发解决方案,提供了强大的任务调度支持,而Quartz则是一个流行的开源作业调度库,能够与Spring很好地集成。现在,我们就来深入探讨"spring quartz 任务调度"这一主题。 首先,...

    Spring任务调度demo

    本篇文章将深入探讨Spring任务调度的实现方法,以及如何利用Quartz库来增强任务管理能力。 首先,让我们理解Spring的任务调度。Spring通过`@Scheduled`注解提供了一种简单而强大的方式来执行定时任务。这个注解可以...

    Spring Quartz 任务调度

    综上所述,Spring Quartz 为开发者提供了一种强大且灵活的方式来管理任务调度,无论是简单的周期性任务还是复杂的调度场景,都能应对自如。结合 Spring 的特性,可以方便地实现任务的定义、调度、监控和扩展,是企业...

    spring的三种任务调度实现方式lib

    Spring提供了三种主要的任务调度实现方式:Spring内置的任务调度器(TaskScheduler),Quartz Scheduler,以及Spring Batch。下面我们将详细介绍这三种方式。 1. Spring内置的任务调度器(TaskScheduler) Spring...

    spring任务调度实例

    总的来说,Spring任务调度实例提供了实践Quartz和Timer的机会,这对于学习和掌握Spring框架的高级特性和任务调度机制非常有价值。通过学习这个实例,开发者不仅可以提升自己的技能,还能了解到如何在实际项目中选择...

    基于Spring Boot的Quartz任务调度系统.zip

    任务调度支持Cron表达式和单次时间任务的调度。 任务管理提供任务的创建、暂停、重启、删除和修改功能。 接口文档集成Swagger2,提供在线接口文档。 数据库支持使用MySQL存储任务信息,支持逻辑删除。 技术栈 ...

    spring定时任务所需jar

    其次,`spring-context-support.jar`也是必需的,因为它提供了对各种实用工具类库的支持,其中包括了对任务调度的支持。这个jar包中包含了`org.springframework.scheduling`包,里面包含了用于实现定时任务的接口和...

    spring实现任务的自动调度所需的jar包

    在Spring框架中,任务调度是一项重要的功能,它允许开发者安排任务在特定的时间点或周期性地执行。Quartz是一个流行的任务调度库,被广泛用于Java应用程序中,包括Spring项目。在本篇中,我们将深入探讨如何使用...

    Spring quartz 定时任务调度

    Spring Quartz 是一个强大的开源任务调度框架,它允许开发者在Java应用程序中定义和执行定时任务。在Spring框架中集成Quartz,可以充分利用Spring的IoC(Inversion of Control)和AOP(Aspect Oriented Programming...

    Spring+Quartz实现任务调度的小例子

    Spring框架和Quartz是两个广泛使用的工具,它们可以协同工作以实现复杂和灵活的任务调度。本篇文章将深入探讨如何使用Spring与Quartz结合来创建一个任务调度的小例子。 首先,Spring是一个开源的Java企业级应用开发...

    spring整合quartz定时任务调度

    Spring框架作为Java领域广泛使用的轻量级框架,提供了与第三方库Quartz的整合,使得开发者能够轻松地在Spring应用中实现复杂的定时任务调度。Quartz是一款开源的作业调度框架,支持丰富的调度策略,可以满足各种定时...

    maven spring 任务调度实列

    Spring框架提供了一个强大的任务调度模块——Spring Task,也被称为Spring Batch,它支持基于时间的任务调度和基于事件的任务触发。 首先,我们需要在`pom.xml`文件中添加Spring相关的依赖。这通常包括`spring-...

    基于Spring Boot框架的简单任务调度系统.zip

    本项目是一个基于Spring Boot框架的简单任务调度系统,旨在提供一个灵活的任务管理和调度机制。系统支持异步任务处理、动态代理加载、热部署功能,并集成了Swagger用于API文档生成。 适用人群 开发人员需要了解...

    基于Spring Boot和Quartz的分布式任务调度系统.zip

    任务调度支持多种任务类型,包括RPC任务、Cron任务、Groovy任务等。 任务管理支持任务的动态管理,如任务的暂停、更新、触发一次等。 分布式部署支持任务的分布式部署,通过Zookeeper或Redis进行任务的协调与调度...

Global site tag (gtag.js) - Google Analytics