Quartz定时任务学习

187 篇文章 0 订阅

http://hi.baidu.com/xulin_1027/blog/item/def5ba0ac718503bb0351d5f.html

 

学习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 simpleTrigger =
        new SimpleTrigger("simpleTrigger", "triggerGroup-s1");


        //设置作业启动时间

        long ctime = System.currentTimeMillis();
        simpleTrigger.setStartTime(new Date(ctime));


        //设置作业执行间隔
        simpleTrigger.setRepeatInterval(10000);

        //设置作业执行次数
        simpleTrigger.setRepeatCount(10);

        //设置作业执行优先级默认为5
        //simpleTrigger.setPriority(10);


        //作业和触发器设置到调度器中
        scheduler.scheduleJob(jobDetail, simpleTrigger);
       
        //启动调度器
        scheduler.start();
    }


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

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.overWriteExistingJobs = false
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true

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

quartz要使用插件来加载自己的xml配置文件,上面指定加载classes\quartz_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>

 

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

#---------调度器属性----------------
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.overWriteExistingJobs = false
org.quartz.plugin.jobInitializer.failOnFileNotFound = 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.instanceIdinstaneName 属性一样,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 配置和详解

实例:简单触发器

 

  1. <?xml version='1.0' encoding='utf-8'?> 
  2.  
  3. <quartz> 
  4.  
  5.   <job> 
  6.     <job-detail> 
  7.      <name>ScanDirectory</name> 
  8.      <group>DEFAULT</group> 
  9.      <description> 
  10.            A job that scans a directory for files  
  11.      </description> 
  12.      <job-class> 
  13.              org.cavaness.quartzbook.chapter3.ScanDirectoryJob  
  14.      </job-class> 
  15.      <volatility>false</volatility> 
  16.      <durability>false</durability> 
  17.      <recover>false</recover> 
  18.      <job-data-map allows-transient-data="true"> 
  19.          <entry> 
  20.          <key>SCAN_DIR</key> 
  21.          <value>c:\quartz-book\input</value> 
  22.        </entry> 
  23.      </job-data-map> 
  24.     </job-detail> 
  25.  
  26.     <trigger> 
  27.      <simple> 
  28.        <name>scanTrigger</name> 
  29.        <group>DEFAULT</group> 
  30.        <job-name>ScanDirectory</job-name> 
  31.        <job-group>DEFAULT</job-group> 
  32.        <start-time>2005-06-10 6:10:00 PM</start-time> 
  33.        <!-- repeat indefinitely every 10 seconds --> 
  34.        <repeat-count>-1</repeat-count> 
  35.        <repeat-interval>10000</repeat-interval> 
  36.      </simple> 
  37.     </trigger> 
  38.  
  39.   </job> 
  40. </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://java.sun.com/products/javabeans/glasgow/jaf.html
commons-beanutils.jarhttp://jakarta.apache.org/commons/beanutils
commons-collections.jarhttp://jakarta.apache.org/commons/collections
commons-dbcp-1.1.jar是,假如用到数据库作为作业存储http://jakarta.apache.org/commons/dbcp
commons-digester.jar假如你使用了某些插件,就需要它
commons-logging.jarhttp://jakarta.apache.org/commons/logging/
commons-pool-1.1.jar http://jakarta.apache.org/commons/pool/
javamail.jar发送 e-mail 用http://java.sun.com/products/javamail/
jdbc2_0-stdext.jar是,假如用到数据库作为作业存储http://java.sun.com/products/jdbc/
jta.jar是,假如用到数据库作为作业存储http://java.sun.com/products/jta/database
quartz.jarQuart 框架核心包
servlet.jar假如使用了Servlet 容器,但容器中应该存在http://java.sun.com/products/servlet/
log4j.jar是,日志http://logging.apache.org/

org.quartz.Scheduler 类层次

QuartzFigure4.2.JPG

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

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

QuartzFigure4.3.JPG

使用 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_CLASS,"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 去执行,public void standby() throws SchedulerException; standby 模式,Scheduler 不再试图去执行 Job,因为那些搜寻要执行的 Job 的线程被暂停了下来。停止则调用无参的 shutdown() 方法相当于调用 shutdown(false).

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值