jBPM用户指南 第8章 Quartz Job Scheduling Framework (转载)

Quartz Job Scheduling Framework第8章翻译初稿 续

 

You can have as many properties as you need to configure your plug-in.

你可以用多个属性配置插件。

Plug-In Properties Must Have set() Methods

插件属性必须含有set()方法

You must provide a setXXX() method for each property you intend to pass to the plug-in class. Quartz throws a SchedulerException and halts the Scheduler if it can't find a public setXXX() method for the property. Based on the JavaBean specification, you should provide both get() and set() methods for the properties.

 

你必须为预传递插件类的每个属性提供setXXX()方法。如果Scheduler找不到属性publicsetXXX()方法Quartz会抛出SchedulerException并中断Scheduler。依据JavaBean规范,你必须提供每个属性的get()set()方法。

 

The Quartz framework converts the property values to the type specified in the plug-in, assuming that it's a primitive type. For example, you can specify properties of type int and expect Quartz to convert the String from the quartz.properties file to an int. The framework, however, will not convert 1 to an integer class.

 

Quartz会将属性值转换为插件中定义的类型,假定该类型是基本数据类型。例如你可以指定参数为intQuartz会将quartz.properties中的字符串转换为int值。然而框架不会将1转换为Integer类。

 

Quartz Uses Introspection to Set Values

Quartz使用反射机制赋值

 

Quartz uses introspection and reflection to convert the parameter values in the quartz.properties file to their correct type in the plug-in class. You might have guessed that it uses the Common BeanUtils from Jakarata, but this isn't the case yet.

Quartz使用自省(introspection译者注:Introspection就是类的getset方法,也就是类设定和获取自身属性值的方法。)和反射机制将quartz.properties内的信息转换为插件中需要的类型。你可能猜测框架使用了Jakarata的公共BeanUtils,但事实并非如此。



Creating the Job File for the JobLoaderPlugin

创建JobLoaderPlugin使用的Job文件

 

The JobLoaderPlugin looks for all XML files in the specified directory and assumes that each file is a valid Quartz jobs file. By "valid," we mean that the XML file adheres to the latest job-scheduling XSD file, which at the time of this writing is job_scheduling_data_1_5.xsd.

 

JobLoaderPlugin在指定的文件夹中查找所有的XML文件并假定这些文件都是合法的Quartz job定义文件。所谓“合法”值XML遵循最新的作业调度XSD文件。在本书编写时最新的版本是job_scheduling_data_1_5.xsd

 

To make the JobLoaderPlugin more useful, we put each job, along with its job detail and trigger information, in a single XML file. This enables us to add and remove complete jobs just by putting the file into the directory or taking it out. This is very helpful in a development environment when you want to test only certain jobs. A single job XML file is shown in Listing 8.4.

 

为了让JobLoaderPlugin更加有用,我们将每个job与它的job detail、触发器信息单独作为一个XML文件。这使得我们添加移除整个job时候只需要将文件添加或移出文件夹。在开发环境中如果我们需要测试某个单独的job的时候这是非常有帮助的。一个单独的job XML文件如列表8.4

 

Listing 8.4. A Job XML File Read by the JobLoaderPlugin

列表8.4 JobLoaderPlugin读取的一个Job XML文件

xml 代码
  1. <?xml version='1.0' encoding='utf-8'?>  
  2.   
  3.   
  4. <quartz xmlns="http://www.opensymphony.com/quartz/JobSchedulingData"  
  5.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.  xsi:schemaLocation="http://www.opensymphony.com/quartz/JobSchedulingData   
  7.  http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.xsd"   
  8.  version="1.5">  
  9.   
  10.  <job>  
  11.    <job-detail>  
  12.      <name>PrintInfoJob1</name>  
  13.      <group>DEFAULT</group>  
  14.      <job-class>  
  15.        org.cavaness.quartzbook.chapter3.ScanDirectoryJob   
  16.      </job-class>  
  17.      <volatility>false</volatility>  
  18.      <durability>false</durability>  
  19.      <recover>false</recover>  
  20.   
  21.      <job-data-map allows-transient-data="true">  
  22.        <entry>  
  23.          <key>SCAN_DIR</key>  
  24.          <value>c:/quartz-book/input1</value>  
  25.        </entry>  
  26.      </job-data-map>  
  27.    </job-detail>  
  28.   
  29.    <trigger>  
  30.      <simple>  
  31.        <name>trigger1</name>  
  32.        <group>DEFAULT</group>  
  33.        <job-name>PrintInfoJob1</job-name>  
  34.        <job-group>DEFAULT</job-group>  
  35.        <start-time>2005-07-30T16:04:00</start-time>  
  36.   
  37.        <!-- repeat indefinitely every 10 seconds -->  
  38.        <repeat-count>-1</repeat-count>  
  39.        <repeat-interval>10000</repeat-interval>  
  40.      </simple>  
  41.    </trigger>  
  42.  </job>  
  43.   
  44.   
  45. </quartz>  
  46.   

 

The job file is Listing 8.4 contains all the information necessary for the JobLoaderPlugin to schedule the job. This file also contains an entry for the JobDataMap, which is available to the job class at runtime. The example in Listing 8.4 uses a configured SimpleTrigger to schedule an infinitely repeating trigger that fires every 10 seconds. To further test the plug-in, we created a second job file, which differs from the first in some small way. Listing 8.5 shows the second job file.

 

列表8.4显示的job文件包含所有的供JobLoaderPlugin调度job所需要的信息。这个文件还包含一个可以在类中实时供JobDataMap调用的实体。列表8.4战士的例子使用SimpleTrigger。它频率是没10秒一次,无限循环。为了更进一步测试插件,我们创建第2job文件,与第一个相比有一些小不同。列表8.5显示了第2job文件。

 

Listing 8.5. A Second Job XML File Loaded by the JobLoaderPlugin

列表8.5 JobLoaderPlugin加载的第2个job XML文件

xml 代码
  1. <?xml version='1.0' encoding='utf-8'?>  
  2.   
  3. <quartz xmlns="http://www.opensymphony.com/quartz/JobSchedulingData"  
  4.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.  xsi:schemaLocation="http://www.opensymphony.com/quartz/JobSchedulingData   
  6.  http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.xsd"   
  7.  version="1.5">  
  8.   
  9.  <job>  
  10.    <job-detail>  
  11.      <name>PrintInfoJob2</name>  
  12.      <group>DEFAULT</group>  
  13.      <job-class>  
  14.        org.cavaness.quartzbook.chapter3.ScanDirectoryJob</job-class>  
  15.      <volatility>false</volatility>  
  16.      <durability>false</durability>  
  17.      <recover>false</recover>  
  18.   
  19.      <job-data-map allows-transient-data="true">  
  20.         <entry>  
  21.          <key>SCAN_DIR</key>  
  22.           <value>c:/quartz-book/input2</value>  
  23.         </entry>  
  24.      </job-data-map>  
  25.   
  26.    </job-detail>  
  27.   
  28.     <trigger>  
  29.      <simple>  
  30.        <name>trigger2</name>  
  31.        <group>DEFAULT</group>  
  32.        <job-name>PrintInfoJob2</job-name>  
  33.        <job-group>DEFAULT</job-group>  
  34.        <start-time>2005-07-30T16:04:00</start-time>  
  35.        <!-- repeat indefinitely every 10 seconds -->  
  36.        <repeat-count>-1</repeat-count>  
  37.        <repeat-interval>60000</repeat-interval>  
  38.      </simple>  
  39.    </trigger>  
  40.  </job>  
  41.   
  42. </quartz>  
  43.   

 

The second job file in Listing 8.5 differs only slightly from the one in Listing 8.4. We've changed the directory for the job, which is scanned and changed the trigger schedule. The point here is that you can have multiple jobs in the jobs directory, and the JobLoaderPlugin will load them all and schedule them individually with the Scheduler.

 

列表8.5显示的第2job文件与8.4显示的第一个相比只有一点不同。我们改变了搜索改变触发调度作业的文件夹。有一点注意的是你可以放多个job文件到文件夹中,JobLoaderPlugin将分别加载并用Scheduler调度他们。(老外就是这样说了好几遍还罗嗦^_^

 

Using Multiple Plug-Ins

使用多个插件

You can register as many plug-ins in the quartz.properties file as you like. However, the order of loading and initialization can't be guaranteed because Quartz loads all the properties into a map and then loops through the plug-ins in the order that they are retrieved from the map.

 

你可以在quartz.properties文件中注册任意多个插件。然而加载初始化的顺序不能保证,因为Quartz加载所有的属性到Map中然后按map的中的顺序查找插件。

 

To get around this limitation, you can create a Quartz plug-in that acts as a parent plug-in and loads multiple other plug-ins in a given order. Listing 8.6 shows what the ParentPlugin looks like.

 

为绕开这一限制,你可以建立一个Quartz插件做为其他插件的父插件。该插件按指定顺序加载其他插件。列表8.6展示了父插件的样子。

 

Listing 8.6. The ParentPlugin Can Load Child Plug-Ins in a Specified Order

列表8.6 父插件可以按指定顺序加载子插件

java 代码
  1. package org.cavaness.quartzbook.chapter8;   
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.List;   
  5. import java.util.StringTokenizer;   
  6.   
  7. import org.apache.commons.logging.Log;   
  8. import org.apache.commons.logging.LogFactory;   
  9. import org.quartz.Scheduler;   
  10. import org.quartz.SchedulerConfigException;   
  11. import org.quartz.SchedulerException;   
  12. import org.quartz.spi.SchedulerPlugin;   
  13.   
  14. public class ParentPlugin implements SchedulerPlugin {   
  15.     private static Log logger = LogFactory.getLog(ParentPlugin.class);   
  16.   
  17. // A list of child plug-ins   
  18. //子插件列表   
  19.     private List childPlugins = new ArrayList();   
  20.   
  21.     private String childPluginNames;   
  22.   
  23.     private String pluginName;   
  24.   
  25.     private Scheduler scheduler;   
  26.   
  27.     /**  
  28.      * Default no-arg Constructor  
  29.      *  
  30.      */  
  31.     public ParentPlugin() {   
  32.     }   
  33.   
  34.     /**  
  35.      * Pass the initialize call on to the child plug-ins.  
  36.      *  
  37.      * @throws SchedulerConfigException  
  38.      *             if there is an error initializing.  
  39.      */  
  40.   
  41. public void initialize(String name, final Scheduler scheduler)   
  42.               throws SchedulerException {   
  43.   
  44.          this.pluginName = name;   
  45.          this.scheduler = scheduler;   
  46.   
  47.          logger.info("Searching for child plugins to load");   
  48.   
  49.          // The child plug-ins are comma-separated   
  50.          StringTokenizer tokenizer =   
  51.               new StringTokenizer(childPluginNames, ",");   
  52.   
  53.          while (tokenizer.hasMoreElements()) {   
  54.               String pluginClassname = tokenizer.nextToken();   
  55.   
  56.               try {   
  57.                    Class pluginClass =   
  58.                         Class.forName(pluginClassname);   
  59.   
  60.                    Object obj = pluginClass.newInstance();   
  61.   
  62.                    // Make sure the specified class is a plug-in   
  63.                    if (obj instanceof SchedulerPlugin) {   
  64.                         // Initialize the Plugin   
  65.                         SchedulerPlugin childPlugin =   
  66.                               (SchedulerPlugin) obj;   
  67.   
  68.                              logger.info("Init child Plugin " +   
  69.                                   pluginClassname);   
  70.   
  71.                         childPlugin.initialize(pluginClassname,   
  72.                              scheduler);   
  73.   
  74.                         // Store the child plug-in in the list   
  75.                         childPlugins.add(childPlugin);   
  76.                    } else {   
  77.                         // Skip loading class   
  78.                         logger.error("Class is not a plugin " +   
  79.                              pluginClass);   
  80.                    }   
  81.   
  82.               } catch (Exception ex) {   
  83.                    // On error, log and go to next child plug-in   
  84.                    logger.error("Error loading plugin " +   
  85.                         pluginClassname, ex);   
  86.               }   
  87.          }   
  88.     }   
  89.     public void start() {   
  90.          // Start each child plug-in   
  91.          int size = childPlugins.size();   
  92.          for (int i = 0; i < size; i++) {   
  93.               SchedulerPlugin childPlugin =   
  94.                    ((SchedulerPlugin) childPlugins.get(i));   
  95.   
  96.               logger.info("Starting Child Plugin " + childPlugin);   
  97.               childPlugin.start();   
  98.          }   
  99.     }   
  100.   
  101.     public void shutdown() {   
  102.          // Stop each child plug-in   
  103.          int size = childPlugins.size();   
  104.          for (int i = 0; i < size; i++) {   
  105.               SchedulerPlugin childPlugin =   
  106.                    ((SchedulerPlugin) childPlugins.get(i));   
  107.   
  108.               logger.info("Stopping Plugin " + childPlugin);   
  109.               childPlugin.shutdown();   
  110.          }   
  111.     }   
  112.   
  113.     public String getPluginName() {   
  114.          return pluginName;   
  115.     }   
  116.   
  117.     public void setPluginName(String pluginName) {   
  118.          this.pluginName = pluginName;   
  119.     }   
  120.   
  121.     public String getChildPluginNames() {   
  122.          return childPluginNames;   
  123.     }   
  124.   
  125.     public void setChildPluginNames(String childPluginNames) {   
  126.          this.childPluginNames = childPluginNames;   
  127.     }   
  128. }   
  129.  &nbs
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值