`

spring-Quartz(入门一)

阅读更多
创建一个 Java 工程,引入几个 JAR 到工程中才能成功构建它们。首先,你需要 Quartz 的二进制版本,包的名字是 quartz-<version>.jar。Quartz 还需要几个第三方库;这依赖于你要用到框架的什么功能而定,Commons Digester 库可以在 <QUARTZ_HOME>/lib/core 和 <QUARTZ_HOME>/lib/optional 目录中找到。如果出现java.lang.NoClassDefFoundError: javax/transaction/UserTransaction的错误,解决办法是:引入jta.jar包,这个包在quartz-1.6.0/lib/build 下。

·创建一个 Quartz Job 类

每一个 Quartz Job 必须有一个实现了 org.quartz.Job 接口的具体类。这个接口仅有一个要你在 Job 中实现的方法,execute(),方法 execute() 的原型如下:
public void execute(JobExecutionContext context) throws JobExecutionException;

当 Quartz 调度器确定到时间要激发一个 Job 的时候,它就会生成一个 Job 实例,并调用这个实例的 execute() 方法。调度器只管调用 execute() 方法,而不关心执行的结果,除了在作业执行中出问题抛出的 org.quartz.JobExecutionException 异常。

下面是我们的第一个 Quartz job,它被设计来扫描一个目录中的文并显示文件的详细信息。

package com.vista.quartz;
import java.io.File;      
import java.io.FileFilter;
import java.util.Date;      
     
import org.apache.commons.logging.Log;      
import org.apache.commons.logging.LogFactory;      
import org.quartz.Job;      
import org.quartz.JobDataMap;      
import org.quartz.JobDetail;      
import org.quartz.JobExecutionContext;      
import org.quartz.JobExecutionException; 

public class ScanDirectoryJob implements Job
{
    static Log logger = LogFactory.getLog(ScanDirectoryJob.class);//日志记录器
   
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
        //Every job has its own job detail      
        JobDetail jobDetail = context.getJobDetail();      
        // The name is defined in the job definition      
        String jobName = jobDetail.getName();//任务名称      
        // Log the time the job started      
        logger.info(jobName + " fired at " + new Date());//记录任务开始执行的时间      
        // The directory to scan is stored in the job map      
        JobDataMap dataMap = jobDetail.getJobDataMap();//任务所配置的数据映射表      
        String dirName = dataMap.getString("SCAN_DIR");//获取要扫描的目录      
        // Validate the required input      
        if (dirName == null)
        {//所需要的扫描目录没有提供      
             throw new JobExecutionException( "Directory not configured" );      
        }      
        // Make sure the directory exists      
        File dir = new File(dirName);      
        if (!dir.exists())
        {//提供的是错误目录      
            throw new JobExecutionException( "Invalid Dir "+ dirName);      
        }      
        // Use FileFilter to get only XML files      
        FileFilter filter = new FileExtensionFileFilter(".xml");      
        //只统计xml文件
        File[] files = dir.listFiles(filter);      
        if (files == null || files.length <= 0)
        {//目录下没有xml文件      
            logger.info("No XML files found in " + dir);      
            // Return since there were no files      
            return;
        }      
        // The number of XML files      
        int size = files.length;         
        // Iterate through the files found      
        for (int i = 0; i < size; i++)
        {
            File file = files[i];      
            // Log something interesting about each file.      
            File aFile = file.getAbsoluteFile();      
            long fileSize = file.length();      
            String msg = aFile + " - Size: " + fileSize;      
            logger.info(msg);//记录下文件的路径和大小
        }
    }
}

     当 Quartz 调用 execute() 方法,会传递一个 org.quartz.JobExecutionContext 上下文变量,里面封装有 Quartz 的运行时环境和当前正执行的 Job。通过 JobexecutionContext,你可以访问到调度器的信息,作业和作业上的触发器的信息,还有更多更多的信息。在代码中,JobExecutionContext 被用来访问 org.quartz.JobDetail 类,JobDetail 类持有 Job 的详细信息,包括为 Job 实例指定的名称,Job 所属组,Job 是否被持久化(易失性),和许多其他感兴趣的属性。

JobDetail 又持有一个指向 org.quartz.JobDataMap 的引用。JobDataMap 中有为指定 Job 配置的自定义属性。例如,在代码中我们从 JobDataMap 中获得欲扫描的目录名,我们可以在 ScanDirectoryJob 中硬编码这个目录名,但是这样的话我们难以重用这个 Job 来扫描别的目录了。在后面你将会看到目录是如何配置到 JobDataMap 的。

execute() 方法中剩下的就是标准 Java 代码了:获得目录名并创建一个 java.io.File 对象。它还对目录名作为简单的校验,确保是一个有效且存在的目录。接着调用 File 对象的 listFiles() 方法得到目录下的文件。还创建了一个 java.io.FileFilter 对象作为参数传递给 listFiles() 方法。org.quartzbook.cavaness.FileExtensionFileFilter 实现了 java.io.FileFilter 接口,它的作用是过滤掉目录仅返回 XML 文件。默认情况下,listFiles() 方法是返回目录中所有内容,不管是文件还是子目录,所以我们必须过滤一下,因为我们只对 XML 文件感兴趣。

FileExtensionFileFilter 被用来屏蔽名称中不含字符串 “.xml” 的文件。它还屏蔽了子目录--这些子目录原本会让 listFiles() 方法正常返回。过滤器提供了一种很便利的方式选择性的向你的 Quartz 作业提供它能接受的作为输入的文件

package com.vista.quartz;
import  java.io.File;      
import  java.io.FileFilter;  

public class FileExtensionFileFilter implements  FileFilter
{
     private  String extension;//文件后缀    
    
     public  FileExtensionFileFilter(String extension)
     {      
         this.extension = extension;
     }            
     public   boolean  accept(File file)
     {//只接受指定后缀的文件      
         // Lowercase the filename for easier comparison      
         String lCaseFilename = file.getName().toLowerCase();//小写化
         return  (file.isFile() &&(lCaseFilename.indexOf(extension) >  0 )) ?  true : false ;      
     }      
}

到目前为止,我们已经创建了一个 Quartz job,但还没有决定怎么处置它--明显地,我们需以某种方式为这个 Job 设置一个运行时间表。时间表可以是一次性的事件,或者我们可能会安装它在除周日之外的每个午夜执行。你即刻将会看到,Quartz Schduler 是框架的心脏与灵魂。所有的 Job 都通过 Schduler 注册;必要时,Scheduler 也会创建 Job 类的实例,并执行实例的 execute() 方法。

·编程式安排一个 Quartz Job

所有的要 Quartz 来执行的作业必须通过调度器来注册。大多情况下,这会在调度器启动前做好。正如前面说过,这一操作也提供了声明式与编程式两种实现途径的选择。

因为每一个 Job 都必须用 Scheduler 来注册,所以先定义一个 JobDetail,并关联到这个 Scheduler 实例。

下面的程序提供了一个理解如何编程式安排一个 Job 很好的例子。代码首先调用 createScheduler() 方法从 Scheduler 工厂获取一个 Scheduler 的实例。得到 Scheduler 实例之后,把它传递给 schedulerJob() 方法,由它把 Job 同 Scheduler 进行关联。

首先,创建了我们想要运行的 Job 的 JobDetail 对象。JobDetail 构造器的参数中包含指派给 Job 的名称,逻辑组名,和实现 org.quartz.Job 接口的全限类名称。我们可以使用 JobDetail 的别的构造器。

在前面有说过,JobDetail 扮演着某一 Job 定义的角色。它带有 Job 实例的属性,能在运行时被所关联的 Job 访问到。其中在使用 JobDetail 时,的一个最重要的东西就是 JobDataMap,它被用来存放 Job 实例的状态和参数。在代码中,待扫描的目录名称就是通过  scheduleJob() 方法存入到 JobDataMap 中的。

Job 只是一个部分而已。注意我们没有在 JobDetail 对象中为 Job 设定执行日期和次数。这是 Quartz Trigger 该做的事。顾名思义,Trigger 的责任就是触发一个 Job 去执行。当用 Scheduler 注册一个 Job 的时候要创建一个 Trigger 与这个 Job 相关联。Quartz 提供了四种类型的 Trigger,但其中两种是最为常用的,它们就是在下面要用到的 SimpleTrigger 和  CronTrigger.

SimpleTrigger 是两个之中简单的那个,它主要用来激发单事件的 Job,Trigger 在指定时间激发,并重复 n 次--两次激发时间之间的延时为 m,然后结束作业。CronTrigger 非常复杂且强大。它是基于通用的公历,当需要用一种较复杂的时间表去执行一个 Job 时用到。例如,四月至九月的每个星期一、星期三、或星期五的午夜。

为更简单的使用 Trigger,Quartz 包含了一个工具类,叫做 org.quartz.TriggerUtils. TriggerUtils 提供了许多便捷的方法简化了构造和配置 trigger. 本文的例子中有用的就是 TriggerUtils 类;SimpleTrigger 和 CronTrigger 会在后面用到。

正如你看到的那样,调用了 TriggerUtils 的方法 makeSecondlyTrigger() 来创建一个每10秒种激发一次的 trigger(实际是由 TriggerUtils 生成了一个 SimpleTrigger 实例,但是我们的代码并不想知道这些)。我们同样要给这个 trigger 实例一个名称并告诉它何时激发相应的 Job;与之关联的 Job 会立即启动,因为由方法 setStartTime() 设定的是当前时间

package com.vista.quartz;

import java.util.Date;      

import org.apache.commons.logging.Log;      
import org.apache.commons.logging.LogFactory;      
import org.quartz.JobDetail;
import org.quartz.Scheduler;      
import org.quartz.SchedulerException;      
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

public class SimpleScheduler
{
    static Log logger = LogFactory.getLog(SimpleScheduler.class);        
    public static void main(String[] args)
    {      
         SimpleScheduler simple = new SimpleScheduler();      
         try
         {      
             // Create a Scheduler and schedule the Job      
             Scheduler scheduler = simple.createScheduler();      
             simple.scheduleJob(scheduler);      
   
             // Start the Scheduler running      
             scheduler.start();      
   
             logger.info( "Scheduler started at " + new Date());      
   
        } catch (SchedulerException ex) {      
             logger.error(ex);      
        }  
       
    }      
    public Scheduler createScheduler() throws SchedulerException
    {//创建调度器      
        return StdSchedulerFactory.getDefaultScheduler();
    }  
   
    //Create and Schedule a ScanDirectoryJob with the Scheduler      
    private void scheduleJob(Scheduler scheduler) throws SchedulerException
    {      
         // Create a JobDetail for the Job      
         JobDetail jobDetail = new JobDetail("ScanDirectory",Scheduler.DEFAULT_GROUP,ScanDirectoryJob.class);
         // Configure the directory to scan      
         jobDetail.getJobDataMap().put("SCAN_DIR","D:\\Tomcat\\conf"); //set the JobDataMap that is associated with the Job.           
         // Create a trigger that fires every 10 seconds, forever      
         Trigger trigger = TriggerUtils.makeSecondlyTrigger(10);//每10秒触发一次      
         trigger.setName("scanTrigger");      
         // Start the trigger firing from now      
         trigger.setStartTime(new Date());//设置第一次触发时间           
         // Associate the trigger with the job in the scheduler      
         scheduler.scheduleJob(jobDetail, trigger);      
    }      
}


     假如你有不只一个个 Job (你也许就是),你将需要为每一个 Job 创建各自的 JobDetail。每一个 JobDetail 必须通过 scheduleJob() 方法一一注册到 Scheduler 上。而如果你想重用了一个 Job 类,让它产生多个实例运行,那么你需要为每个实例都创建一个 JobDetail。例如,假如你想重用 ScanDirectoryJob 让它检查两个不同的目录,你需要创建并注册两个 JobDetail 实例

package com.vista.quartz;

import java.util.Date;      

import org.apache.commons.logging.Log;      
import org.apache.commons.logging.LogFactory;      
import org.quartz.JobDetail;
import org.quartz.Scheduler;      
import org.quartz.SchedulerException;      
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

public class SimpleScheduler
{
    static Log logger = LogFactory.getLog(SimpleScheduler.class);        
    public static void main(String[] args)
    {      
         SimpleScheduler simple = new SimpleScheduler();      
         try
         {      
             // Create a Scheduler and schedule the Job      
             Scheduler scheduler = simple.createScheduler();        
             // Jobs can be scheduled after Scheduler is running      
             scheduler.start();         
             logger.info("Scheduler started at " + new Date());        
             // Schedule the first Job      
             simple.scheduleJob(scheduler, "ScanDirectory1",ScanDirectoryJob.class,"D:\\conf1", 10);         
             // Schedule the second Job      
             simple.scheduleJob(scheduler, "ScanDirectory2",ScanDirectoryJob.class,"D:\\conf2 ", 15);      
        }
        catch (SchedulerException ex)
        {      
             logger.error(ex);      
        }      
    }      
    public Scheduler createScheduler() throws SchedulerException
    {//创建调度器      
        return StdSchedulerFactory.getDefaultScheduler();
    }  
   
    private void scheduleJob(Scheduler scheduler, String jobName,Class jobClass, String scanDir, int scanInterval) throws SchedulerException
    {        
        // Create a JobDetail for the Job      
       JobDetail jobDetail = new JobDetail(jobName,Scheduler.DEFAULT_GROUP, jobClass);        
       // Configure the directory to scan      
       jobDetail.getJobDataMap().put("SCAN_DIR", scanDir);        
       // Trigger that repeats every "scanInterval" secs forever      
       Trigger trigger = TriggerUtils.makeSecondlyTrigger(scanInterval);        
       trigger.setName(jobName + "-Trigger");        
       // Start the trigger firing from now      
       trigger.setStartTime(new Date());        
       // Associate the trigger with the job in the scheduler      
       scheduler.scheduleJob(jobDetail, trigger);      
  }      
}

分享到:
评论

相关推荐

    quartz和spring-quartz

    Quartz和Spring-Quartz是两个在Java世界...“spring-quartz-demo”可能是一个完整的示例项目,你可以通过运行它来深入理解Quartz在Spring中的应用。通过研究这些资源,你可以更全面地掌握Quartz和Spring-Quartz的用法。

    spring-boot示例项目

    该项目包含helloworld(快速入门)、web(ssh项目快速搭建)、aop(切面编程)、data-redis(redis缓存)、quartz(集群任务实现)、shiro(权限管理)、oauth2(四种认证模式)、shign(接口参数防篡改重放)、encoder(用户...

    spring-boot学习demo.zip_DEMO_SpringBoot_spring boot_spring-boot_sp

    SpringBoot学习Demo是一个针对初学者的入门项目,旨在帮助开发者快速理解并掌握Spring Boot的核心概念和用法。Spring Boot是Spring框架的一个模块,它简化了创建独立的、生产级别的基于Spring的应用程序的过程,通过...

    spring入门经典

    《Spring入门经典》这本书是Java开发者入门Spring Framework的理想选择,它深入浅出地阐述了Spring的核心概念和技术。Spring Framework作为Java开发领域的主流框架,它的应用广泛且功能强大,旨在简化企业级应用程序...

    quartz实例,quartz入门例子

    在这个Quartz入门例子中,可能包含了一个名为`QuarzTest`的类或配置文件,它是实际运行的入口。通过分析和运行这个例子,你可以了解到如何在Spring中配置和使用Quartz,以及如何创建和调度Job。 学习Quartz时,你...

    spring-boot-demo实例.rar

    Spring Boot 的快速入门通常从创建一个 Maven 或 Gradle 项目开始,引入 `spring-boot-starter-web` 依赖,这将包含 Spring Web MVC 和 Tomcat 服务器。在 `main` 方法中使用 `SpringApplication.run` 启动应用,就...

    spring-boot-study-master.zip

    本篇将基于"spring-boot-study-master.zip"这一压缩包,深入探讨Spring Boot的核心概念及实战应用,包括Druid、Ehcache、JWT、Mybatis、Generator、Quartz、Scheduling、Shiro以及Upload等模块,旨在帮助初学者从零...

    quartz入门例子,spring集成配置使用

    Spring集成quartz跑定时任务实例 自己写的例子并为实现job 有测试的主函数,请参考...springCon.quartz文件夹下 为对上诉博客理解透彻 结合spring看其配置的相关信息 就可以明白。

    spring-boot-helloworld.zip

    在 "spring-boot-helloworld.zip" 这个压缩包中,我们很可能是找到了一篇关于 Spring Boot 入门的博客文章示例代码,用于展示如何构建一个简单的 "Hello World" 应用。 在 Spring Boot 中创建一个 "Hello World" ...

    Java分布式Elastic-Job和Quartz定时任务课程(1.6G)

    1_什么事定时任务.mp4 2_为什么学习定时任务.mp4 3_定时任务技术发展趋势.mp4 4_主流定时任务框架优缺点和什么是分布式定时任务.mp4 5_环境搭建总体流程.mp4 6_前期准备-JDK.mp4 ...24_Spring_Boot整合Simp

    spring整合quartz

    Spring整合Quartz是一个常见的任务调度解决方案,用于在Java应用程序中执行定时任务。Quartz是一个功能强大的、开放源代码的作业调度框架,而Spring框架则提供了一种优雅的方式来管理和集成Quartz到我们的应用中。让...

    quartz案例,包括spring配置设置调度器和入门手册

    3. **Quartz入门** - **创建Job类**:你需要创建一个实现了`org.quartz.Job`接口的类,这个类定义了具体要执行的任务。 - **定义Trigger**:你可以选择不同的`Trigger`类型,如SimpleTrigger或CronTrigger,来决定...

    Quartz入门学习(真丶入门)

    二、Quartz入门 1. **创建作业**:首先,你需要创建一个实现了`org.quartz.Job`接口的类,这个类就是你的任务逻辑。在`execute()`方法中编写实际的业务代码。 2. **定义触发器**:接着,定义一个触发器,设置执行...

    Spring Boot-RESTfull API入门.rar

    它集成了大量常用的第三方库配置,如 JDBC、MongoDB、JPA、RabbitMQ、Quartz 等,使得开发者能够快速地创建生产级别的基于 Spring 的独立应用程序。 RESTful API(Representational State Transfer)是一种软件架构...

    Spring Boot 教程、技术栈示例代码,快速简单上手教程。

    Spring Boot 是一个由 Pivotal 团队开发的框架,旨在简化 Spring 应用程序的初始搭建以及开发过程。它集成了大量常用的第三方库配置,如 JDBC、MongoDB、RabbitMQ、Quartz 等,使得开发者可以“零配置”地启动项目,...

    quartz-2.1.6.zip

    QUICK-START.html 是Quartz的快速入门指南,它通常会提供关于如何安装、配置和启动Quartz的基本步骤,以及如何创建和执行第一个作业的示例。通过阅读这份文档,开发者能够迅速理解Quartz的工作原理,并开始自己的...

    spring-quickstart:Spring Boot 快速入门项目

    标题“spring-quickstart:Spring Boot 快速入门项目”表明这是一个帮助开发者快速了解并上手 Spring Boot 的教程或示例项目。这通常包含一系列的代码样例和指导,旨在解释如何创建、配置和运行一个基本的 Spring ...

    springboot的简单入门

    SpringBoot是Spring框架的一个模块,旨在简化Spring应用的初始搭建以及开发过程。它集成了大量常用的第三方库配置,如 JDBC、MongoDB、JPA、RabbitMQ、Quartz 等,让开发者能够快速地“起步运行”(get started)。...

    quartz入门共3页.pdf.zip

    通过阅读 "quartz入门共3页.pdf",你将能够快速了解 Quartz 的基本概念和用法,为实际项目开发打下基础。文件可能涵盖了 Quartz 的安装、基本示例、API 使用方法等内容,帮助你快速上手并掌握这个强大的任务调度库。

    spring boot入门demo

    它集成了大量的常用第三方库配置,如 JDBC、MongoDB、JPA、RabbitMQ、Quartz 等,使得开发者可以快速地创建一个独立运行的、生产级别的基于 Spring 的应用。 在“Spring Boot 入门 Demo”中,我们将探讨以下几个...

Global site tag (gtag.js) - Google Analytics