Quartz 框架快速入门(二)

来源:互联网 发布:怎样建立切片软件 编辑:程序博客网 时间:2024/05/18 00:32
   尽可能的用声明式处理软件配置,其次才考虑编程式的方式。在上一篇《Quartz框架快速入门(一)》中,如果我们要在 Job启动之后改变它的执行时间和频度,必须去修改源代码重新编译。这种方式只适用于小的例子程序,但是对于一个大且复杂的系统,这就成了一个问题了。因此,假如能以声明式部署Quart Job 时,并且也是需求允许的情况下,你应该每次都选择这种方式 

·配置quartz.properties 文件

文件 quartz.properties 定义了 Quartz 应用运行时行为,还包含了许多能控制 Quartz运转的属性。这个文件应该放在classpath所指的路径下,比如我们这个java工程,就将它和下面将介绍的jobs.xml一起放在项目根目录下就是。如果不清楚就查看.classpath文件,它里面就配置了你的项目的classpath。

我们来看看最基础的 quartz.properties 文件,并讨论其中一些设置。下面是一个修剪版的quartz.propertis文件

#============================================================================
Configure Main Scheduler Properties  
#============================================================================
org.quartz.scheduler.instanceName TestScheduler
org.quartz.scheduler.instanceId AUTO
#============================================================================
Configure ThreadPool  
#============================================================================
org.quartz.threadPool.class org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount 3
org.quartz.threadPool.threadPriority 5
#============================================================================
Configure JobStore  
#============================================================================
org.quartz.jobStore.misfireThreshold 60000
org.quartz.jobStore.class org.quartz.simpl.RAMJobStore
#============================================================================
Configure Plugins 
#============================================================================
org.quartz.plugin.triggHistory.class org.quartz.plugins.history.LoggingJobHistoryPlugin
org.quartz.plugin.jobInitializer.class org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.fileNames jobs.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs true
org.quartz.plugin.jobInitializer.failOnFileNotFound true
org.quartz.plugin.jobInitializer.scanInterval 10
org.quartz.plugin.jobInitializer.wrapInUserTransaction false

·调度器属性

第一部分有两行,分别设置调度器的实例名(instanceName) 和实例 ID(instanceId)。属性 org.quartz.scheduler.instanceName可以是你喜欢的任何字符串。它用来在用到多个调度器区分特定的调度器实例。多个调度器通常用在集群环境中。(Quartz集群将会在第十一章,“Quartz集群”中讨论)。现在的话,设置如下的一个字符串就行:org.quartz.scheduler.instanceName =QuartzScheduler
实际上,这也是当你没有该属性配置时的默认值。

调度器的第二个属性是 org.quartz.scheduler.instanceId。和instaneName 属性一样,instanceId属性也允许任何字符串。这个值必须是在所有调度器实例中是唯一的,尤其是在一个集群当中。假如你想 Quartz帮你生成这个值的话,可以设置为 AUTO。如果 Quartz 框架是运行在非集群环境中,那么自动产生的值将会是NON_CLUSTERED。假如是在集群环境下使用 Quartz,这个值将会是主机名加上当前的日期和时间。大多情况下,设置为 AUTO即可。
·线程池属性

接下来的部分是设置有关线程必要的属性值,这些线程在 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,它能够满足大多数用户的需求。这个线程池实现具备简单的行为,并经很好的测试过。它在调度器的生命周期中提供固定大小的线程池。你能根据需求创建自己的线程池实现,如果你想要一个随需可伸缩的线程池时也许需要这么做。这个属性没有默认值,你必须为其指定值。

·作业存储设置

作业存储部分的设置描述了在调度器实例的生命周期中,Job 和 Trigger信息是如何被存储的。我们还没有谈论到作业存储和它的目的;因为对当前例子是非必的,所以我们留待以后说明。现在的话,你所要了解的就是我们存储调度器信息在内存中而不是在关系型数据库中就行了。

把调度器信息存储在内存中非常的快也易于配置。当调度器进程一旦被终止,所有的 Job 和 Trigger的状态就丢失了。要使 Job 存储在内存中需通过设置 org.quartz.jobStrore.class 属性为org.quartz.simpl.RAMJobStore。假如我们不希望在 JVM退出之后丢失调度器的状态信息的话,我们可以使用关系型数据库来存储这些信息。这需要另一个作业存储(JobStore)实现,我们在后面将会讨论到。第五章“Cron Trigger和其他”和第六章“作业存储和持久化”会提到你需要用到的不同类型的作业存储实现。
·插件配置

在这个简单的 quartz.properties 文件中最后一部分是你要用到的 Quart插件的配置。插件常常在别的开源框架上使用到,比如 Apache 的 Struts 框架(见 http://struts.apache.org/)。

一个声明式扩框架的方法就是通过新加实现了 org.quartz.spi.SchedulerPlugin接口的类。SchedulerPlugin  接口中有给调度器调用的三个方法。

要在我们的例子中声明式配置调度器信息,我们会用到一个 Quartz 自带的叫做org.quartz.plugins.xml.JobInitializationPlugin 的插件。

默认时,这个插件会在 classpath 中搜索名为 quartz_jobs.xml 的文件并从中加载Job 和 Trigger 信息。在下下面中讨论 quartz_jobs.xml 文件,这是我们所参考的非正式的 Job定义文件。

·为插件修改quartz.properties 配置

JobInitializationPlugin 找寻 quartz_jobs.xml 来获得声明的Job 信息。假如你想改变这个文件名,你需要修改 quartz.properties 来告诉插件去加载那个文件。例如,假如你想要Quartz 从名为 my_quartz_jobs.xml 的 XML 文件中加载 Job 信息,你不得不为插件指定这一文件

org.quartz.plugin.triggHistory.class org.quartz.plugins.history.LoggingJobHistoryPlugin
org.quartz.plugin.jobInitializer.class org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.fileNames jobs.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs true
org.quartz.plugin.jobInitializer.failOnFileNotFound true
org.quartz.plugin.jobInitializer.scanInterval 10
org.quartz.plugin.jobInitializer.wrapInUserTransaction false

我们添加了属性 org.quartz.plugin.jobInitializer.fileName并设置该属性值为我们想要的文件名。这个文件名要对 classloader 可见,也就是说要在 classpath 下。

当 Quartz 启动后读取 quartz.properties文件,然后初始化插件。它会传递上面配置的所有属性给插件,这时候插件也就得到通知去搜寻不同的文件。

下面就是目录扫描例子的 Job 定义的 XML 文件。正如上一篇所示例子那样,这里我们用的是声明式途径来配置 Job 和Trigger 信息的

<?xml version='1.0' encoding='utf-8'?>
<quartz xmlns="http://www.opensymphony.com/quartz/JobSchedulingData"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opensymphony.com/quartz/JobSchedulingData
  http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.xsd"
  version="1.5">   
  <job>      
    <job-detail>      
     <name>ScanDirectory</name>      
     <group>DEFAULT</group>      
     <description>      
          job that scans directory for files       
     </description>      
     <job-class>      
            com.vista.quartz.ScanDirectoryJob       
     </job-class>      
     <volatility>false</volatility>      
     <durability>false</durability>      
     <recover>false</recover>      
     <job-data-map allows-transient-data="true">      
         <entry>      
         <key>SCAN_DIR</key>      
         <value>D:\conf1</value>      
       </entry>      
     </job-data-map>      
    </job-detail>      
      
    <trigger>      
     <simple>      
       <name>scanTrigger</name>      
       <group>DEFAULT</group>      
       <job-name>ScanDirectory</job-name>      
       <job-group>DEFAULT</job-group>      
       <start-time>2008-09-03T14:43:00</start-time>      
       <!-- repeat indefinitely every 10 seconds -->      
       <repeat-count>-1</repeat-count>      
       <repeat-interval>10000</repeat-interval>      
     </simple>      
    </trigger>      
  </job>      
</quartz>

在jobs.xml 中 <start-time> 的格式是:

<start-time>2008-09-03T14:43:00</start-time>

其中T隔开日期和时间,默认时区
或者:

<start-time>2008-09-03T14:43:00+08:00</start-time> 

其中+08:00 表示东八区

<job> 元素描述了一个要注册到调度器上的Job,相当于我们在前面章节中使用 scheduleJob()方法那样。你所看到的<job-detail>和  <trigger>这两个元素就是我们在代码中以编程式传递给方法 schedulerJob()的参数。前面本质上是与这里一样的,只是现在用的是一种较流行声明的方式。<trigger>元素也是非常直观的:它使用前面同样的属性,但更简单的建立一个SimpleTrigger。因此仅仅是一种不同的(可论证的且更好的)方式做了上一篇代码 中同样的事情。显然,你也可以支持多个Job。在上一篇代码 中我们编程的方式那么做的,也能用声明的方式来支持


<?xml version='1.0' encoding='utf-8'?>
<quartz xmlns="http://www.opensymphony.com/quartz/JobSchedulingData"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opensymphony.com/quartz/JobSchedulingData
  http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.xsd"
  version="1.5">   
 <job>      
    <job-detail>      
     <name>ScanDirectory1</name>      
     <group>DEFAULT</group>      
     <description>      
           job that scans directory for files       
     </description>      
     <job-class>      
            com.vista.quartz.ScanDirectoryJob       
     </job-class>      
     <volatility>false</volatility>      
     <durability>false</durability>      
     <recover>false</recover>      
      
     <job-data-map allows-transient-data="true">      
     <entry>      
       <key>SCAN_DIR</key>      
         <value>D:\dyk\Java\Tomcat\conf</value>      
     </entry>      
    </job-data-map>      
  </job-detail>      
  <trigger>      
    <simple>      
     <name>scanTrigger1</name>      
     <group>DEFAULT</group>      
     <job-name>ScanDirectory1</job-name>      
     <job-group>DEFAULT</job-group>      
     <start-time>2008-09-03T15:00:10</start-time>      
     <!-- repeat indefinitely every 10 seconds -->      
     <repeat-count>-1</repeat-count>      
     <repeat-interval>10000</repeat-interval>      
    </simple>      
  </trigger>      
</job>       
<job>      
  <job-detail>      
    <name>ScanDirectory2</name>      
    <group>DEFAULT</group>      
    <description>      
          job that scans directory for files       
    </description>      
    <job-class>      
          com.vista.quartz.ScanDirectoryJob       
    </job-class>      
    <volatility>false</volatility>      
    <durability>false</durability>      
    <recover>false</recover>      
    <job-data-map allows-transient-data="true">      
      <entry>      
       <key>SCAN_DIR</key>      
       <value>D:\dyk\Java\Tomcat\webapps\MyTest\WEB-INF</value>      
     </entry>      
    </job-data-map>      
  </job-detail>      
  <trigger>      
    <simple>      
     <name>scanTrigger2</name>      
     <group>DEFAULT</group>      
     <job-name>ScanDirectory2</job-name>      
     <job-group>DEFAULT</job-group>      
     <start-time>2008-09-03T15:00:20</start-time>      
     <!-- repeat indefinitely every 15 seconds -->      
     <repeat-count>-1</repeat-count>      
     <repeat-interval>15000</repeat-interval>      
    </simple>      
  </trigger>      
 </job>   
</quartz>

最后我们来看看原来的代码简化成如何了:

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 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());         
        
        catch (SchedulerException ex)
              
             logger.error(ex);       
              
          
    public Scheduler createScheduler() throws SchedulerException 
    {//创建调度器       
        return StdSchedulerFactory.getDefaultScheduler();
      
}

 

作者:洞庭散人

出处:http://phinecos.cnblogs.com/    

本博客遵从Creative Commons Attribution 3.0License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 a1a2驾驶证扣3分怎么办 车辆累计扣12分怎么办 驾照扣了40分怎么办 驾驶证扣了30分怎么办 b2驾照逾期未审怎么办 c1实习期扣6分怎么办 车子累计扣30分怎么办 实习期间扣满12分怎么办 新手驾照扣6分怎么办 a2驾驶证逾期未审验怎么办 c1驾照扣了6分怎么办 b1驾照被扣12分怎么办 b2驾驶本扣分了怎么办 驾驶本扣9分后怎么办 b1照扣12分怎么办 b2扣了15分怎么办 b2有扣分未年审怎么办 b2驾驶证扣4分怎么办 b2驾驶证扣10分怎么办 刚发驾驶证照片太丑想换怎么办! 考驾照时户口变更怎么办 驾照年审色盲未过怎么办 考驾驶证互联网注册号码怎么办 驾驶证体检视力不过关怎么办 六年驾照满了怎么办 驾照扣了40多分怎么办 一个驾照扣24分怎么办 南昌电动车牌照丢了怎么办 上海餐饮工作人员怎么办健康证 房产过户没有遗嘱公证怎么办 在外地被扣12分怎么办 公务员体检视力不过关怎么办弱视 身份证被盗用注册公司怎么办 驾照分卖了12分怎么办 一年12分扣完了怎么办 滴滴车管所信息不同步怎么办 驾驶证过期两个月了怎么办 科目二考试第一次不合格怎么办 科目二不想考了怎么办 科二有事考不了怎么办 科四有事去不了怎么办