现在的位置: 首页 > 综合 > 正文

Quartz定时任务学习

2013年12月11日 ⁄ 综合 ⁄ 共 10574字 ⁄ 字号 评论关闭

(一)简单任务

学习quartz首先了解三个概念:

调度器:负责调度作业和触发器;

触发器:设置作业执行的时间、参数、条件等;(简单触发器和Cron触发器)

作业:定时任务内容,被执行的程序;

下载必要的jar包,将quartz-x.x.x.jar 和core 和/或 optional 文件夹中的 jar 文件放在项目的文件夹或项目的类路径中 Quartz的几个核心的接口和类为:

Job接口:自己写的“定时程序”实现此接口的void execute(JobExecutionContext arg0)方法,Job还有一类为有状态的StatefulJob接口,假如我们需要在上一个作业执行完后,根据其执行结果再进行下次作业的执行,则需要实现此接口。

Trigger抽象类:调度类(Scheduler)在时间到时调用此类,再由trigger类调用指定的定时程序。

Quertz中提供了两类触发器为:SimpleTrigger,CronTrigger。前者用于实现比较简单的定时功能,例如几点开始,几点结束,隔多长时间执行,共执行多少次等,后者提供了使用表达式来描述定时功能,因此适用于比较复杂的定时描述,例如每个月的最后一个周五,每周的周四等。

JobDetail类:具体某个定时程序的具体描述,包括Name,Group,JobDataMap等。

JobExecutionContext类:定时程序执行的run-time的上下文环境,用于得到当前执行的Job的名字,配置的参数等。

JobDataMap类:用于描述一个作业的参数,参数可以为任何基本类型例如String,float等,也可为某个对象的引用.

JobListener,TriggerListener接口:用于监听触发器状态和作业扫行状态,在特写状态执行相应操纵。

JobStore类:在哪里执行定进程序,可选的有在内存中,在数据库中。

开始:边看例题边学习,首先从简单触发器开始…… 1、作业通过实现org.quartz.job接口,可以使 Java 类变成可执行的。这个类用一条非常简单的输出语句覆盖了execute(JobExecutionContext context)方法。 import java.util.Date;

import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

public class SimpleQuartzJob implements Job {

public SimpleQuartzJob() {

}

public void execute(JobExecutionContext context) throws JobExecutionException {

System.out.println("In SimpleQuartzJob - executing its JOB at "

+ new Date() + " by " + context.getTrigger().getName());

}

} 2、触发器和调度器

public void task() throws SchedulerException

{

//通过SchedulerFactory来获取一个调度器

SchedulerFactory schedulerFactory = new StdSchedulerFactory();

Scheduler scheduler = schedulerFactory.getScheduler();

//引进作业程序

JobDetail jobDetail =

new JobDetail("jobDetail-s1", "jobDetailGroup-s1", SimpleQuartzJob.class);

//new一个触发器

SimpleTrigger ***Trigger =

new SimpleTrigger("***Trigger", "triggerGroup-s1");

//设置作业启动时间

long ctime = System.currentTimeMillis();

***Trigger.setStartTime(new Date(ctime));

//设置作业执行间隔

***Trigger.setRepeatInterval();

//设置作业执行次数

***Trigger.setRepeatCount(10);

//设置作业执行优先级默以为5

//***Trigger.setPriority(10);

//作业和触发器设置到调度器中

scheduler.scheduleJob(jobDetail, ***Trigger);

//启动调度器

scheduler.start();

}

一个简单的quartz任务就完成了。

-------------------------------------------------- --------------------------------------------------- --------------------------------------------------- --------------------

(二)web应用

web中使用Quartz

1、首先在web.xml文件中加进 如下内容(根据自己情况设定)

在web.xml中添加QuartzInitializerServlet,Quartz为能够在web应用中使用,提供了一个QuartzInitializerServlet和一个QuartzInitializerListener,用于在加载web应用时,对quartz进行初始化。

<servlet>

<servlet-name>

QuartzInitializer

</servlet-name>

<servlet-class>

org.quartz.ee.servlet.QuartzInitializerServlet

</servlet-class>

<init-param>

<param-name>config-file</param-name>

<param-value>/quartz.properties</param-value>

</init-param>

<init-param>

<param-name>shutdown-on-unload</param-name>

<param-value>true</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

2、quartz.properties文件的配置(各项属性说明下次写),内容如下:

上面提到了quartz.properties,这是自行指定的,Quartz提供了一个默认的配置文件,可以满足基本的j2se应用,假如在web应用中,我们想把job,trigger配置都写到文件中,就需要自己来写,并指定在初始化时加载我们自己的quratz.properties,位置放在classes下。

org.quartz.scheduler.instanceName = TestScheduler

org.quartz.scheduler.instanceId = one

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount = 2

org.quartz.threadPool.threadPriority = 4

org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin

org.quartz.plugin.jobInitializer.fileName = quartz_job.xml

org.quartz.plugin.jobInitializer.overWriteExisting Jobs = false

org.quartz.plugin.jobInitializer.failOnFileNotFoun d = true

org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin

org.quartz.plugin.shutdownhook.cleanShutdown = true

3、 quartz_job.xml文件配置(各项属性说明下次写),内容如下:

quartz要使用插件来加载自己的xml配置文件,上面指定加载classesquartz_job.xml文件。

以Quartz定时任务学习(一)中的简单作业SimpleQuartzJob为例子:

<?xml version="1.0" encoding="UTF-8"?>

<quartz>

<job>

<job-detail>

<name>listener1</name>

<group>group1</group>

<job-class>SimpleQuartzJob</job-class>

</job-detail>

<trigger>

<cron>

<name>job1</name>

<group>group1</group>

<job-name>listener1</job-name>

<job-group>group1</job-group>

<cron-expression>0/10 * * * * ?</cron-expression>

</cron>

</trigger>

</job>

</quartz>

-------------------------------------------------- --------------------------------------------------- --------------------------------------------------- --------------------

(三)属性文件和jar

以下是我在应用的的一个基本配置:

#---------调度器属性----------------

org.quartz.scheduler.instanceName = TestScheduler

org.quartz.scheduler.instanceId = one

#---------线程配置---------------

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount = 2

org.quartz.threadPool.threadPriority = 4

#---------作业存储设置------------

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

#---------插件配置-------------

org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin

org.quartz.plugin.jobInitializer.fileName = quartz_job.xml

org.quartz.plugin.jobInitializer.overWriteExisting Jobs = false

org.quartz.plugin.jobInitializer.failOnFileNotFoun d = true

org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin

org.quartz.plugin.shutdownhook.cleanShutdown = true

属性的先容

1.调度器属性:分别设置调度器的实例名(instanceName) 和实例 ID (instanceId)。属性 org.quartz.scheduler.instanceName 可以是你喜欢的任何字符串。默认名字一般都采用QuartzScheduler,第二个属性org.quartz.scheduler.instanceId和instaneName 属性一样,instanceId 属性也答应任何字符串。这个值必须是在所有调度器实例中是唯一的,尤其是在一个集群当中。假如你想 Quartz 帮你天生这个值的话,可以设置为
AUTO。

2、线程池属性:这些线程在 Quartz 中是运行在后台担当重任的。threadCount 属性控制了多少个工作者线程被创建用来处理 Job。原则上是,要处理的 Job 越多,那么需要的工作者线程也就越多。threadCount 的数值至少为 1。Quartz 没有限定你设置工作者线程的最大值,但是在多数机器上设置该值超过100的话就会显得相当不实用了,特别是在你的 Job 执行时间较长的情况下。这项没有默认值,所以你必须为这个属性设定一个值。

threadPriority 属性设置工作者线程的优先级。优先级别高的线程比级别低的线程更优先得到执行。threadPriority 属性的最大值是常量 java.lang.Thread.MAX_PRIORITY,即是10。最小值为常量 java.lang.Thread.MIN_PRIORITY,为1。这个属性的正常值是 Thread.NORM_PRIORITY,为5。大多情况下,把它设置为5,这也是没指定该属性的默认值。

最后一个要设置的线程池属性是 org.quartz.threadPool.class。这个值是一个实现了 org.quartz.spi.ThreadPool 接口的类的全限名称。Quartz 自带的线程池实现类是 org.quartz.smpl.SimpleThreadPool,它能够满足大多数用户的需求。这个线程池实现具备简单的行为,并经很好的测试过。它在调度器的生命周期中提供固定大小的线程池。你能根据需求创建自己的线程池实现,假如你想要一个随需可伸缩的线程池时也许需要这么做。这个属性没有默认值,你必须为其指定值。

3、作业存储属性:作业存储部分的设置描述了在调度器实例的生命周期中,Job 和 Trigger 信息是如何被存储的。把调度器信息存储在内存中非常的快也易于配置。当调度器进程一旦被终止,所有的 Job 和 Trigger 的状态就丢失了。要使 Job 存储在内存中需通过设置 org.quartz.jobStrore.class 属性为 org.quartz.simpl.RAMJobStore,在Cron Trigger 和“作业存储和持久化”会用到的不同类型的作业存储实现。

4、网络电话哪个好其他插件属性:org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin默认时,JobInitializationPlugin插件会在 classpath 中搜索名为 quartz_jobs.xml 的文件并从中加载 Job 和 Trigger 信息。其他插件后叙……

quartz_jobs.xml配置和详解

实例:简单触发器

<?xmlversion='1.0'encoding='utf-8'?>

<quartz>

<job>

<job-detail>

<name>ScanDirectory</name>

<group>DEFAULT</group>

<description>A job that scans a directory for files</description>

<job-class>

org.cavaness.quartzbook.chapter3.ScanDirectoryJob

</job-class>

<volatility>false</volatility>

<durability>false</durability>

<recover>false</recover>

<job-data-mapallows-transient-data="true">

<entry>

<key>SCAN_DIR</key>

<value>c:quartz-bookinput</value>

</entry>

</job-data-map> </job-detail> <trigger> <***> <name>scanTrigger</name> <group>DEFAULT</group> <job-name>ScanDirectory</job-name> <job-group>DEFAULT</job-group> <start-time>2005-06-10 6:10:00 PM</start-time> <!-- repeat indefinitely every 10 seconds --> <repeat-count>-1</repeat-count>
<repeat-interval></repeat-interval> </***> </trigger> </job> </quartz> 我们添加了属性 org.quartz.plugin.jobInitializer.fileName 并设置该属性值为我们想要的文件名。这个文件名要对 classloader 可见,也就是说要在 classpath 下。

第三方包

通过测试。一个简单任务只需要以下几个包:commons-beanutils.jar、commons-collections.jar、commons-logging.jar、commons-digester.jar、quartz.jar即可

名称 必须/备注 网址

activation.jar 主要是 JavaMail 要用到 http:///products/javabeans/glasgow/jaf .html

commons-beanutils.jar 是 http:///commons/beanutils

commons-collections.jar 是 http:///commons/collections

commons-dbcp-1.1.jar 是,假如用到数据库作为作业存储 http:///commons/dbcp

commons-digester.jar 是 假如你使用了某些插件,就需要它

commons-logging.jar 是 http:///commons/logging/

commons-pool-1.1.jar http://jakarta.apache.org/commons/pool/

javamail.jar 发送 e-mail 用 http:///products/javamail/

jdbc2_0-stdext.jar 是,假如用到数据库作为作业存储 http:///products/jdbc/

jta.jar 是,假如用到数据库作为作业存储 http:///products/jta/database

quartz.jar 是 Quart 框架核心包

servlet.jar 假如使用了Servlet 容器,但容器中应该存在 http:///products/servlet/

log4j.jar 是,日志 http:///

-------------------------------------------------- ------------------------------------------------ org.quartz.Scheduler 类层次

作为一个 Quartz 用户,你要与实现了 org.quartz.Scheduler 接口的类交互。在你调用它的任何 API 之前,你需要知道如何创建一个 Scheduler 的实例。取而代之的是用了某个工厂方法来确保了构造出 Sheduler 实例并正确的得到初始化,Quartz 框架为这一目的提供了 org.quartz.SchedulerFactory 接口。角色 SchedulerFactory 就是用来产生 Scheduler 实例的。当 Scheduler 实例被创建之后,就会存到一个仓库中(org.quartz.impl.SchedulerRepository),这个仓库还提供了通过一个
class loader 查询实例的机制。要使用 Scheduler 实例,客户端必须从工厂(和随同的仓库中)使用不同方法调用来获取到它们。换句话说,要通过工厂创建一个 Scheduler 实例并获取到它需要经过两次方法调用。

所有的 Scheduler 实例应该由 SchedulerFactory 来创建

使用 DirectSchedulerFactory 构造实例方法代码如下:

DirectSchedulerFactory factory=DirectSchedulerFactory.getInstance();

try {

// Initialize the Scheduler Factory with 10 threads

factory.createVolatileScheduler(10);

// Get a scheduler from the factory

Scheduler scheduler = factory.getScheduler();

方法 createVolatileScheduler() 方法不会返回 scheduler 的实例。createXXX() 方法是告诉工厂如何配置要创建的 Scheduler 实例。你必须调用方法 getScheduler() 获取到在工厂上执行方法 createXXX() 产生的实例。实际上,在调用 getScheduler() 方法之前,你必须调用其中一个 createXXX() 方法;否则,你将有收到一个 SchedulerException 错误,由于根本没有 Scheduler 实例存在。

方法 createVolatileScheduler() 带有单个参数:要创建的线程数目。

使用 StdSchedulerFactory 构造一个调度器实例,具体使用方法如下:

StdSchedulerFactory factory = new StdSchedulerFactory();

// Create the properties to configure the factory

Properties props = new Properties();

// required to supply threadpool class and num of threads

props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLA SS,"org.quartz.simpl.SimpleThreadPool");

props.put("org.quartz.threadPool.threadCount", "10");

try {

// Initialize the factory with properties

factory.initialize(props);

Scheduler scheduler = factory.getScheduler();

在这个例子中向工厂传递了两个属性,它们分别是实现了 org.quartz.spi.ThreadPool 接口的类名和 Scheduler 用来处理 Job 的线程的数目。这两个属性是必须的。但是我们也可以这样的得到实例

StdSchedulerFactory factory = new StdSchedulerFactory();

Scheduler scheduler = factory.getScheduler();

由于StdSchedulerFactory工厂类会有个方法initialize()自动往加载一些属性配置,假如你使用无参的initialize() 方法,StdSchedulerFactory会取classpath下找到quartz.properties并加载。默认不配置属性时候会自动加载quartz.properties文件的配置。

使用静态的 getDefaultScheduler() 方法创建 Scheduler

使用 StdSchedulerFactory 来创建 Scheduler 实例的方式很普遍,因此在 StdSchedulerFactory 直接提供了一个方便的静态方法 getDefaultScheduler(),它就是使用前面列出的几个步骤来初始化工厂的。

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

在静态方法 getDefaultScheduler() 方法中调用了空的构造方法。假如之前未调用过任何一个 initialize() 方法,那么无参的 initialize() 方法会被调用。这会开始往按照前面说的顺序加载文件。默认情况下,quartz.properties 会被定位到,并从中加载属性。

Scheduler 的功能

Scheduler除了启动外,Scheduler操纵包括查询、设置 Scheduler 为 standby 模式、继续、停止。启动Scheduler非常简单,只需要调用 start() 方法即可。只有在Scheduler 有实例或standby 模式才能调用start() 方法,一旦调用shutdown() 方法之后就不能在调用start() 方法。

设置 Scheduler 为 standby 模式会导致 Scheduler 暂时停止查找 Job 往执行,publicvoidstandby()throwsSchedulerException; standby 模式,Scheduler 不再试图往执行 Job,由于那些搜寻要执行的 Job 的线程被暂停了下来。停止则调用无参的 shutdown() 方法相当于调用 shutdown(false).

抱歉!评论已关闭.