(翻译)Quartz官方教程——第二课:Quartz API, Jobs 和 Triggers

Quartz的常用API

Quartz API的关键接口如下所示:

  • Scheduler - 与调度器(scheduler)交互的主要API
  • Job - 你想要调度器执行的任务组件需要实现的接口
  • JobDetail - 用来定义任务实例
  • Trigger - 定义给定的任务执行时间的组件
  • JobBuilder - 用来构建JobDetail实例
  • TriggerBuilder - 用来构建Trigger实例

一个调度器(Scheduler的生命周期是从被调度器工厂(SchedulerFactory)创建开始,直到调用它本身的shutdown()方法为止。一旦被创建,Scheduler接口就可以用来新增、删除或者列出当前的任务(Jobs)和触发器(Triggers),或者执行其他调度相关的操作(比如暂停一个触发器)。然而,在调度器使用start()方法启动之前,它不会执行任何触发器(执行任务),就是课程1中展示的那样。

Quartz提供了定义领域特定语言的“构建器”类(也叫DSL,有时也被叫做“流式接口”)。在上一课中你已经看到了一个构建器的例子,这里我们再把部分代码贴出来:


  // define the job and tie it to our HelloJob class
  JobDetail job = newJob(HelloJob.class)
      .withIdentity("myJob", "group1") // name "myJob", group "group1"
      .build();

  // Trigger the job to run now, and then every 40 seconds
  Trigger trigger = newTrigger()
      .withIdentity("myTrigger", "group1")
      .startNow()
      .withSchedule(simpleSchedule()
          .withIntervalInSeconds(40)
          .repeatForever())            
      .build();

  // Tell quartz to schedule the job using our trigger
  sched.scheduleJob(job, trigger);

上述代码中构建任务定义使用了从JobBuilder类静态导入的方法。同样的,构建触发器使用了从TriggerBuilder类静态导入的方法 - 以及SimpleScheduleBulder

静态导入的语句如下所示:

import static org.quartz.JobBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
import static org.quartz.CronScheduleBuilder.*;
import static org.quartz.CalendarIntervalScheduleBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.DateBuilder.*;

不同的“ScheduleBuilder”类有着构建不同类型的schedules的方法。

DateBuilder类包含了很多可以轻松构建特殊时间点的java.util.Date实例的方法(比如代表下一个偶数小时的日期 - 换句话说如果它现在是9:43:27,那么取到10:00:00)。

任务和触发器(Jobs and Triggers)

一个任务就是一个实现了Job接口的类,Job接口只有一个简单的方法:


  package org.quartz;

  public interface Job {

    public void execute(JobExecutionContext context)
      throws JobExecutionException;
  }

当任务的触发器被触发时(稍后再讲这个),execute(...)方法被调度器的某个工人线程(worker threads)调用。传递给方法的JobExecutionContext参数给任务实例提供了运行时环境的信息——一个执行它的调度程序的引用,一个触发它的触发器的引用,任务的JobDetail对象以及一些其他参数。

JobDetail对象是在Quartz客户端(即你的代码)把任务添加到调度器中的时候创建的。它包含Job的各种属性设置以及一个JobDataMap,它可以用来存储你给定的任务实例的状态信息。它本质上是作业实例的定义,在下一课中将进一步详细讨论。

Trigger对象被用来触发任务的执行。当你想要调度一个任务的时候,你实例化一个触发器并“调整”它的属性来满足你的调度需求。触发器可能同样有一个关联的JobDataMap——这对于将参数传递给特定于触发器触发的作业非常有用。Quartz提供了一些不同的触发器类型,但最常用的类型是SimpleTrigger和CronTrigger。

当你的任务只需要执行一次或者你想要任务在一个给定的时间点以固定时间间隔重复N次,SimpleTrigger可以很轻松的实现。而当你想要实现类似于日历的调度功能——比如“每周五的中午”或者“每月10号10:15”,可以使用CronTrigger。

为什么将任务和触发器分开?许多任务调度框架没有单独的作业和触发器概念。一些框架仅简单的将一个有着标识符的执行时间(或者调度)叫做“任务”。而有些框架则更像是Quartz的任务和触发器对象的结合。当我们开发Quartz的时候,我们认为把调度器和在调度器上执行的任务做个区分是有必要的。(在我们看来)这有很多好处。

举个栗子,任务可以独立于触发器创建并存储在任务调度器中,然后多个触发器可以关联到同一个任务上。另一个拆分开的好处是当一个任务关联的触发器都过期时,你仍然可以对任务进行修改,然后任务可以被重新调度,而不需要重新定义它。同样,当你修改或替换一个触发器的时候也不需要重新定义它所关联的任务。

标识符(Identities)

当任务和触发器注册到Quartz调度器时都会被分配一个唯一标识。任务和触发器的键(JobKey和TriggerKey)允许它们被放置到“组”中,这可以用于组织任务和触发器,例如“报告任务”和“维护任务”。任务或触发器的键名称部分在组内必须是唯一的——换句话说,任务或触发器的完整键(或标识符)是名称和组的组合。

现在你对任务和触发器有了一个整体的概念,你可以在课程3:关于工作和工作详情的更多信息以及课程4:关于触发器的更多信息学习到更多知识。

猜你喜欢

转载自my.oschina.net/icebergxty/blog/1797812
今日推荐