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

Quartz 的使用

    博客分类:
  • java
阅读更多
Quartz 的使用
Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。Quartz 允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。虽然可以通过属性文件(在属性文件中可以指定 JDBC 事务的数据源、全局作业和/或触发器侦听器、插件、线程池,以及更多)配置 Quartz,但它根本没有与应用程序服务器的上下文或引用集成在一起。结果就是作业不能访问 Web 服务器的内部函数。

本文内容
宋体Using Quartz
Jobs And Triggers
More About Triggers
More About Jobs & JobDetails
SimpleTrigger
CronTrigger
TriggerListeners and JobListeners
SchedulerListeners
JobStores
Configuration, Resource Usage and SchedulerFactory
关于Quartz中的几个表

Using Quartz
宋体Scheduler的实例化,我们需要使用SchedulerFactory.他也可以通过JNDI实例化
Scheduler被实例化他就可以启动,放置一些行为,关闭。注意:一个Scheduler被关闭,他不能通过新的实例重新启动。Triggers 不能被触发(execute方法),直到它已经启动才可以,在Scheduler停止时,也不能出发

代码片段
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
Scheduler sched = schedFact.getScheduler();
sched.start();
JobDetail jobDetail = new JobDetail("myJob", null, DumbJob.class);
Trigger trigger = TriggerUtils.makeHourlyTrigger(); // 每小时触发一次 trigger.setStartTime(TriggerUtils.getEvenHourDate(new Date()));
//设置开始时间为下一个小时
trigger.setName("myTrigger");
sched.scheduleJob(jobDetail, trigger);

//可以看下TriggerUtils类 设定时间的

Jobs And Triggers
Scheduler作业类,必须实现org.quartz.Job接口,实现execute方法
如:
package org.quartz;
  public interface Job {
    public void execute(JobExecutionContext context)
      throws JobExecutionException; }
不难猜到当job的trigger触发时,execute()方法将被Scheduler调用
JobExecutionContext 对象被传递到方法中,提供关于“run-time” 环境的信息。
JobDetail 对象被Quartz client创建,添加Job到这个scheduler中,他包含不用的属性设置,为了Job、JobDataMap (可以保存一些信息给你job class的实例。)
Trigger 对象触发job的execute,它同样可以有JobDataMap ,它可以有不同的类型,但一般用SimpleTrigger and CronTrigger.
SimpleTrigger如果你需要‘one-shot’ 执行(在某个时间执行一个任务,或者在某个时候开始执行,并在一段时间内执行n次,)
CronTrigger 按一个calendar-like 执行,如每年的……时候执行。
Scheduler好处是将,时间表和任务分开了。如,工作可以被创建和存储,而不依赖一个触发,许多触发可以联合多个工作。另一个是loose-coupling (松耦合)
Jobs and triggers 可以被放在‘groups’ 中,便于管理,job的名字和triggers 在一个组必须是唯一的。Identifiers :name+group. Job or Triggerd的组为 ‘null’,相当与指定Scheduler.DEFAULT_GROUP.

More About Triggers
Calendar Interface
package org.quartz;
  public interface Calendar {
    public boolean isTimeIncluded(long timeStamp);
    public long getNextIncludedTime(long timeStamp);  }

Using Calendars
HolidayCalendar cal = new HolidayCalendar();
cal.addExcludedDate( someDate );
sched.addCalendar("myHolidays", cal, false);
  Trigger trigger = TriggerUtils.makeHourlyTrigger(); // fire every one hour interval
  trigger.setStartTime(TriggerUtils.getEvenHourDate(new Date()));  // start on the next even hour
  trigger.setName("myTrigger1");
  trigger.setCalendarName("myHolidays");
  // .. schedule job with trigger
  Trigger trigger2 = TriggerUtils.makeDailyTrigger(8, 0); // fire every day at 08:00
  trigger.setStartTime(new Date()); // begin immediately
  trigger2.setName("myTrigger2");
  trigger2.setCalendarName("myHolidays");
  // .. schedule job with trigger2
More About Jobs & JobDetails
public class DumbJob implements Job {
    public DumbJob() {  }
    public void execute(JobExecutionContext context)
      throws JobExecutionException
    {      System.err.println("DumbJob is executing.");    }  }
1、must have a no-arguement constructor
2、their values would be 'cleared' every time the job executes

provide properties/configuration for a Job instance 使用   JobDataMap
JobDataMap
Setting Values in a JobDataMap
jobDetail.getJobDataMap().put("jobSays", "Hello World!"); jobDetail.getJobDataMap().put("myFloatValue", 3.141f); jobDetail.getJobDataMap().put("myStateData", new ArrayList());

Getting Values from a JobDataMap
public class DumbJob implements Job {
    public DumbJob() {   }     //必须的
    public void execute(JobExecutionContext context)
      throws JobExecutionException
    {  String instName = context.getJobDetail().getName();
      String instGroup = context.getJobDetail().getGroup();
      JobDataMap dataMap = context.getJobDetail().getJobDataMap();
      String jobSays = dataMap.getString("jobSays");
      float myFloatValue = dataMap.getFloat("myFloatValue");
      ArrayList state = (ArrayList)dataMap.get("myStateData");
      state.add(new Date());
      System.err.println("Instance " + instName + " of DumbJob says: " + jobSays);  } }
Triggers can also have JobDataMaps associated with them
Getting Values from the JobExecutionContext convenience/merged JobDataMap
public class DumbJob implements Job {
    public DumbJob() { }
    public void execute(JobExecutionContext context)
      throws JobExecutionException
    {    String instName = context.getJobDetail().getName();
      String instGroup = context.getJobDetail().getGroup();
      JobDataMap dataMap = context.getJobDataMap();
// Note the difference from the previous example
      String jobSays = dataMap.getString("jobSays");
      float myFloatValue = dataMap.getFloat("myFloatValue");
      ArrayList state = (ArrayList)dataMap.get("myStateData");
      state.add(new Date());
      System.err.println("Instance " + instName + " of DumbJob says: " + jobSays);   } }
It is a merge of the JobDataMap found on the JobDetail and the one found on the Trigger, with the value in the latter overriding any same-named values in the former.

在两次作业执行之间,不会去维护作业执行时JobDataMap的状态改变。
如果你需要能增、删,改JobDataMap的值,而且能让作业在下次执行时能看到这个状态改变,
则需要用Quartz有状态作业。
有状态作业实现了org.quartz.StatefulJob接口。
SimpleTrigger
SimpleTrigger 实例相当原始。在创建对象之后,设置几个基本属性以立即调度任务。还有其他许多方式可以操纵 SimpleTrigger。除了指定重复次数和重复间隔,还可以指定作业在特定日历时间执行,只需给定执行的最长时间或者优先级(稍后讨论)。执行的最长时间可以覆盖指定的重复次数,从而确保作业的运行不会超过最长时间。

One of SimpleTrigger's Constructors
public SimpleTrigger(String name, String group, Date startTime, Date endTime,
int repeatCount, long repeatInterval)

Misfire Instruction Constants of SimpleTrigger
MISFIRE_INSTRUCTION_FIRE_NOW
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT

CronTrigger
CronTrigger 支持比 SimpleTrigger 更具体的调度,而且也不是很复杂。基于 cron 表达式,CronTrigger 支持类似日历的重复间隔,而不是单一的时间间隔
cron 触发器规范:
    Seconds Minutes Hours Day-of-month Month Day-of-Week Year
    秒       分      时     天           月    周          年  
    Seconds            0-59    , - * /
    Minutes            0-59    , - * /
    Hours              0-23    , - * /
    Day-of-month       1-31    , - * ? / L C
    Month              1-12 or JAN-DEC    , - * /
    Day-of-Week        1-7 or SUN-SAT    , - * ? / L C #
    Year (Optional)    empty, 1970-2099    , - * /
    关于字符串的设置(在cron expression中所有字符不区分大小写):

   "*"字符被用来指定所有的值,例如,"*"在分钟字段时表示每一分钟
    "?"字符在天和周字段中使用。表示没有指定值,天和周字段指定一个,但不能两个都指定为"?"
    '-'字符被用来设置范围,比如"10-12"在小时字段的意义为"10点,11点,12点"
    ','字符被用来设置添加的值,例如在周字段设置"MON,WED,FRI"的意义即为:在周一、周三、周五激活
    '/'字符被用来设置增量。例如秒字段设置"0/15"的意思为从0开始,每15秒触发,即在0、15、30、45秒触发,秒字段设置"5/15"的意思为,从5开始,第15秒触发,即在5、20、35、50秒触发.你还可以在'*'后面使用'/'字符,在这种情况下'*'与字符'0'意义相同。
    'L'在天字段和周字段中使用。'L'字符是'last'的缩写,但在两个字段中,它有不同的意义。例如,'L'在天字段的意思为月的最后一天,在一月为31,非闰月2月为28。如果在'L'用在周字段中,意思为'7'(周六),即周末,一周最后一天。但如果在周字段的另一个值后面,他意味着最后一个星期几在指定月。例如'6L'意味着月的最后一个周五.在使用'L'选项时,指定列表或者范围是非常重要的,不然容易被结果搞乱。
    '#'被用在周字段。它用来指定第几个周几中激活。如:"6#3"-->月的第三个周五;"2#1"-->月的第一个周一;"4#5"-->月的第五个周三。要注意,如果要使用#后面跟5,但当月并没有第五周相应的周天,那么job将不被执行(激活);
    'C'被用在天和周字段中,'C'是'calendar'的缩写.(不太明白,关于日历的支持还不完善)
    同时在周、天中使用'?'还不完善,目前只在两者中使用一个。
    要注意'?'和'*'在周和天字段带来的影响。
    注意以下例子:
    1、"0 15 10 * * 6L 2002-2005"   在2002至2005年的每月每天的10:15触发。
    2、"0 15 10 ? * 6L 2002-2005"   在2002至2005年的每月的最后一个周五触发。
    1中*表示每天,覆盖了6L(最后一个周五)



TriggerListeners and JobListeners
The org.quartz.TriggerListener Interface
public interface TriggerListener {
    public String getName();
    public void triggerFired(Trigger trigger, JobExecutionContext context);
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context);
    public void triggerMisfired(Trigger trigger);
    public void triggerComplete(Trigger trigger, JobExecutionContext context,
            int triggerInstructionCode);}

The org.quartz.JobListener Interface
public interface JobListener {
    public String getName();
    public void jobToBeExecuted(JobExecutionContext context);
    public void jobExecutionVetoed(JobExecutionContext context);
    public void jobWasExecuted(JobExecutionContext context,
            JobExecutionException jobException);}

Using Your Own Listeners
implements either the org.quartz.TriggerListener and/or org.quartz.JobListener interface
"global" or "non-global".
Global listeners receive events for ALL triggers/jobs, and
non-global listeners receive events only for the specific triggers/jobs that explicitely
name the listener in their getTriggerListenerNames() or getJobListenerNames() properties.

Adding a JobListener to the Scheduler
scheduler.addGlobalJobListener(myJobListener);
or
scheduler.addJobListener(myJobListener);


SchedulerListeners
The org.quartz.SchedulerListener Interface
public interface SchedulerListener {
    public void jobScheduled(Trigger trigger);
    public void jobUnscheduled(String triggerName, String triggerGroup);
    public void triggerFinalized(Trigger trigger);
    public void triggersPaused(String triggerName, String triggerGroup);
    public void triggersResumed(String triggerName, String triggerGroup);
    public void jobsPaused(String jobName, String jobGroup);
    public void jobsResumed(String jobName, String jobGroup);
    public void schedulerError(String msg, SchedulerException cause);
    public void schedulerShutdown();}

JobStores
Quartz 提供了两种不同的方式用来把与作业和触发器有关的数据保存在内存或数据库中。第一种方式是 RAMJobStore 类的实例,这是默认设置。这个作业仓库最易使用,而且提供了最佳性能,因为所有数据都保存在内存中。这个方法的主要不足是缺乏数据的持久性。因为数据保存在 RAM 中,所以应用程序或系统崩溃时,所有信息都会丢失。
为了修正这个问题,Quartz 提供了 JDBCJobStore。顾名思义,作业仓库通过 JDBC 把所有数据放在数据库中。数据持久性的代价就是性能降低和复杂性的提高。

JDBCJobStore 需要两步:首先必须创建作业仓库使用的数据库表。
    第二,必须定义一些属性
RAMJobStore
Configuring Quartz to use RAMJobStore
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

JDBCJobStore
Configuring Quartz to use JobStoreTx
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
Configuring JDBCJobStore to use a DriverDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
Configuring JDBCJobStore with the Table Prefix
org.quartz.jobStore.tablePrefix = QRTZ_
Configuring JDBCJobStore with the name of the DataSource to use
org.quartz.jobStore.dataSource = myDS
Configuration, Resource Usage and SchedulerFactory
quartz.properties 文件

The major components that need to be configured before Quartz can do its work are:
ThreadPool
JobStore
DataSources (if necessary)
The Scheduler itself

The properties for configuring various aspect of a scheduler are described in these sub-documents:
Main Configuration (configuration of primary scheduler settings, transactions)
Configuration of ThreadPool (tune resources for job execution)
Configuration of Listeners (your application can recieve notification of scheuled events)
Configuration of Plug-Ins (add functionality to your scheduler)
Configuration of RMI Server and Client (use a Quartz instance from a remote process)
Configuration of RAMJobStore (store jobs and triggers in memory)
Configuration of JDBC-JobStoreTX (store jobs and triggers in a database via JDBC)
Configuration of JDBC-JobStoreCMT (JDBC with JTA containter-managed transactions)
Configuration of DataSources (for use by the JDBC-JobStores)
Configuration of Clustering (achieve fail-over and load-balancing with JDBC-JobStore)
关于Quartz中的几个表
QRTZ_TRIGGERS                  
存放Trigger(包括SIMPLE_TRIGGERS和CRON_TRIGGERS)和jobDetail的对应关系
    QRTZ_TRIGGER_LISTENERS
    QRTZ_SIMPLE_TRIGGERS            存储简单触发器 
    QRTZ_SCHEDULER_STATE
    QRTZ_PAUSED_TRIGGER_GRPS
    QRTZ_LOCKS
    QRTZ_JOB_LISTENERS
    QRTZ_JOB_DETAILS                 存储jobDetail
    QRTZ_FIRED_TRIGGERS
    QRTZ_CRON_TRIGGERS               存储复杂触发器CRON_TRIGGERS
    QRTZ_CALENDARS
    QRTZ_BLOB_TRIGGERS 


分享到:
评论

相关推荐

    spring的quartz使用实例

    以下是对Spring整合Quartz使用实例的详细说明: 1. **Quartz简介** Quartz是一个强大的、完全开源的作业调度框架,它支持复杂的调度策略,如按日期、时间间隔或自定义表达式执行。Quartz可以在Java应用中作为独立...

    定时器Quartz使用说明

    ### Quartz 使用说明详解 #### 一、Quartz 功能简介 **Quartz** 是一款开源的任务调度框架,广泛应用于 Java 应用程序中。它的主要功能是帮助开发者以灵活的方式调度任务,支持复杂的触发规则。 - **嵌入式运行**...

    quartz使用例子

    ### Quartz使用例子详解 在Java领域,Quartz是一个强大的任务调度框架,被广泛应用于各种应用场景中,例如定时任务、事件处理等。本文将基于提供的代码片段,深入解析Quartz的使用方法,包括如何定义Job、配置...

    Quartz使用详解

    Quartz 使用详解 Quartz 是一个功能强大的作业调度器,可以帮助开发者实现复杂的任务调度和执行。下面是关于 Quartz 使用详解的知识点总结。 一、实例化 Scheduler 在使用 Quartz 之前, 必须使用 ...

    Quartz使用总结

    ### Quartz使用总结与详解 #### 一、Quartz概述 Quartz是一个开源的任务调度框架,主要功能在于能够根据用户自定义的时间规则来触发任务执行。Quartz提供了丰富的接口供开发者进行二次开发,使得任务调度变得非常...

    quartz使用实例

    - 默认情况下,Quartz使用内存存储作业和触发器信息,但也可以配置使用数据库进行持久化,确保服务器重启后任务不会丢失。 9. **高级特性** - `Stateful Jobs`:有状态的作业,每个实例只执行一次,适合处理不可...

    quartz使用指南

    quartz使用指南,quartz使用指南,quartz使用指南

    Quartz使用小结

    这个小结将深入探讨Quartz的核心概念、使用场景以及如何与Spring框架集成。 一、Quartz简介 Quartz是由Caledonia Software公司开发的Java定时任务库,它提供了一种高度可配置的方式来安排和执行工作。Quartz支持...

    spring+quartz使用jar包

    Spring 和 Quartz 是两个在 Java 开发中非常重要的框架。Spring 是一个全面的后端开发框架,提供了依赖注入、AOP(面向切面编程)、MVC...正确配置和使用这两个框架,能够为企业的后台服务带来极大的灵活性和可维护性。

    spring整合quartz使用jdbc存储

    Quartz本身支持多种持久化策略,包括使用数据库(JDBC)来存储作业和触发器信息,这使得任务调度信息在系统重启后仍能保留。下面将详细介绍如何进行Spring与Quartz的整合,以及使用JDBC存储的相关步骤。 1. **...

    Quartz使用实例

    这个"Quartz使用实例"可能包含一个演示了如何配置和使用Quartz的项目,解压后可以直接运行,这对于初学者或者需要快速理解Quartz工作原理的人来说非常有用。 Quartz的核心概念包括Job(作业)、Trigger(触发器)和...

    quartz使用cron表达式的实例

    本文将深入探讨如何使用Quartz配合cron表达式来实现定时任务的实例。 首先,我们要理解cron表达式。Cron表达式是Unix系统中的定时任务调度工具,也被Quartz框架所采用。它由六个或七个子表达式组成,每个子表达式...

    QuartZ使用1

    Quartz 使用简单、灵活的 API 来创建、管理和执行作业。在本文中,我们将深入探讨如何在 .NET 应用程序中使用 Quartz.NET,这是一个专门为 .NET 平台实现的 Quartz 版本。 首先,要开始使用 Quartz.NET,你需要将 ...

    idea 使用spring自带的定时器quartz 使用的c3p0 v0.95.2所包含的jar

    接下来,为了使用`Quartz`,你需要引入`quartz-spring`库,并配置`Scheduler`: ```xml <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- 其他配置...

    Quartz 线程池

    Quartz 是一个开源的作业调度框架,它允许开发者在 Java 应用程序中安排任务的执行。线程池是 Quartz 的核心组成部分,用于管理和执行触发的任务。本文将深入探讨 Quartz 线程池的工作原理、配置以及如何在实际项目...

    关于spring中quartz的配置

    如果使用的是Spring Boot,可以在`application.properties`或`application.yml`中配置Quartz,并通过`@EnableScheduling`注解启用定时任务支持。 8. **动态管理定时任务** Spring提供的`SchedulerFactoryBean`...

    Quartz使用指南

    8. **集成环境**:Quartz 可以在多种环境中使用,既可以作为独立应用程序,也可以作为 J2EE 应用服务器的组件。它还支持 RMI(远程方法调用)接口,便于远程管理和监控。 9. **灵活性**:Quartz 的灵活性体现在其...

    JAVA定时调度框架-Quartz使用入门到精通.doc

    Quartz 是一个强大的开源作业调度框架,专为 Java 平台设计,无论是 J2SE 还是 J2EE 应用都可以使用。它的主要目的是提供一个简单易用但功能丰富的任务调度解决方案。Quartz 具备数据库支持、集群功能、插件机制、...

    springboot整合quartz定时任务yml文件配置方式

    以下将详细介绍如何在Spring Boot应用中使用YAML文件配置Quartz定时任务,以及涉及的Spring Cloud Alibaba、Dubbo和Nacos的相关知识。 首先,我们需要在`pom.xml`中引入相关的依赖。Spring Boot的`spring-boot-...

Global site tag (gtag.js) - Google Analytics