三. 注册你的插件
当 SchedulerFactory 首次初始化的时候,会从 quartz.properties 文件中搜寻你所配置的 Quartz 插件。它会通过 java.lang.Class 的 newInstance() 方法创建插件的实例。你的插件必须有一个无参的构造方法,像代码中 JobLoaderPlugin 所做的那样。
要在 quartz.properties 文件中注册你的插件的话,需在 quartz.properties 文件中使用如下的格式创建一个属性:
org.quartz.plugin.<pluginName>.class=<fully_qualified_class_name_of_plugin>
Quartz 找寻属性文件中所有含这个关键词的项:
org.quartz.plugin.<pluginName>.class
接着会试图创建等号右边的类的实例,并假定它是一个插件。你通过为 <pluginName> 字段提供一个唯一的名字来命你这个插件。
代码 8.3 展示了一个使用 JobLoaderPlugin 的 quartz.properties 文件。
代码 8.3. 在 quartz.properties 文件中注册 JobLoaderPlugin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#=============================================================== # Configure Main Scheduler Properties #=============================================================== org.quartz.scheduler.instanceName = QuartzScheduler org.quartz.scheduler.instanceId = AUTO #=============================================================== # Configure ThreadPool #=============================================================== org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 5 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.jobLoader.class = org.cavaness.quartzbook.chapter8.JobLoaderPlugin org.quartz.plugin.jobLoader.jobsDirectory = c:\\quartz-book\\sample\\chapter8 |
你应该已经看过了在代码 8.3 的 quartz.properties 文中的大部分设置。最后一台就是用来注册 JobLoaderPlugin 的。
·在 quartz.properties 中指定插件
在初始化和启动期间,Quartz Scheduler 从 quartz.properties 文件中加载属性。你必须在 quartz.properties 文件中指定插件的时候遵循某一特定的格式。这一格式显示如下:
<plugin prefix>.<pluginName><.class>=<fully qualified Plugin class name>
·<plugin prefix> 总是 org.quartz.plugin.
·<pluginName> 是你指派的唯一的名字
·要指定插件类,使用后缀 .class
·右边是插件类的全限名
回头看代码 8.3,你会发现我们的 JobLoaderPlugin 是用了这一格式:
org.quartz.plugin.jobLoader.class=org.cavaness.quartzbook.chapter8.JobLoaderPlugin
指定给这个插件的名字是 jobLoader,可以任意的。我们可以使用任意的名字,只要它区别于其他已注册的插件是唯一的就行。在等号的右边,你必须指定插件类的全限名。这个类必须在 classpath 中或是对于类加载器可见。
·向插件传递参数
多数插件需要配置值,并以此作为好的编程实践,我们不希望把这些值硬编码到插件类中。Quartz 提供了一种机制向你的插件类传递参数,就是在 quartz.properties 文件中提供参数值。
Scheduler 找寻所有的能匹配如下格式的其他属性:
<plugin prefix>.<plugin name>.<property name>=<someValue>
它把把们视为插件类的 JavaBean 属性。从代码 8.3 中来看,意味着这一属性引发对 setJobDirectory() 方法的调用,并传递字符串值 c:\\quartz-book\\sample\\chapter8 作为该方法的参数:
org.quartz.plugin.jobLoader.jobsDirectory=c:\\quartz-book\\sample\\chapter8
你可以有配置给你的插件所需的更多的属性
插件属性必须 set() 方法你必须为你打算传递给插类的每一个属性提供 setXXX() 方法。Quartz 在找不到属生对应的公有 setXXX() 方法时抛出 SchedulerException 异常并终止 Scheduler。基于 JavaBean 规范,你应该为属性提供 get() 和 set() 方法。 |
Quartz 框架转换属性值成插件指定的类型,假定是原始类型,例如,你能指定属性的类型为 int,并期望 Quartz 把 quartz.properties 文件中的字符串转换成一个 int。然而框架不会把 1 转换成一个 Integer 类。
Quartz 使用内省来设值Quartz 使用内省和反射来把 quartz.properties 文件中的参数值转换成插件类中的正确类型。你大约已经猜到它使用了 Jakarata 的 common BeanUtils,但是还不仅如此。 |
·为 JobLoaderPlugin 创建 Job 文件
JobLoaderPlugin 查找指定目录下的所有 XML 文件,并假定每个文件都是有铲的 Quartz Job 文件。我们说 "有效",意思是说 XML 文件是符合最新的 job-scheduling XSD 文件的,写这个的时候是 job_scheduling_data_1_5.xsd。
为使得 JobLoaderPlugin 更有用,我们把每一个 Job,和伴随着它的 JobDetail 和 Trigger 信息放在一个独立的 XML 文件中。这让我们在添加或完全移除 Job 时仅仅是把文件放入到这个目录中或是从中提出来。这对于你在开发环境中只是想测试某些 Job 的时候很有帮助。一个单一个 Job XML 文件如代码 8.4 所示。
代码 8.4. 一个由 JobLoaderPlugin 读取的 Job XML 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?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>PrintInfoJob1</name> <group>DEFAULT</group> <job-class> org.cavaness.quartzbook.chapter3.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>c:\quartz-book\input1</value> </entry> </job-data-map> </job-detail> <trigger> <simple> <name>trigger1</name> <group>DEFAULT</group> <job-name>PrintInfoJob1</job-name> <job-group>DEFAULT</job-group> <start-time>2005-07-30T16:04:00</start-time> <!-- repeat indefinitely every 10 seconds --> <repeat-count>-1</repeat-count> <repeat-interval>10000</repeat-interval> </simple> </trigger> </job> </quartz> |
像代码 8.4 的 Job 文件中包含所有 JobLoaderPlugin 用来部署 Job 所需的信息。这个文件也包含一个 JobDataMap 项,这对于 Job 类运行时是可用的。代码 8.4 中的例子使用一个已配置的 SimpleTrigger 来部署一个以10秒为间隔不断重复的 Trigger。为进一步测试这个插件,我们创建了第二个 Job 文件,与前面的相比只有些许差别。代码 8.5 显示了第二个 Job 文件。
代码 8.5. 由 JobLoaderPlugin 加载的第二个 Job XML 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?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>PrintInfoJob2</name> <group>DEFAULT</group> <job-class> org.cavaness.quartzbook.chapter3.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>c:\quartz-book\input2</value> </entry> </job-data-map> </job-detail> <trigger> <simple> <name>trigger2</name> <group>DEFAULT</group> <job-name>PrintInfoJob2</job-name> <job-group>DEFAULT</job-group> <start-time>2005-07-30T16:04:00</start-time> <!-- repeat indefinitely every 10 seconds --> <repeat-count>-1</repeat-count> <repeat-interval>60000</repeat-interval> </simple> </trigger> </job> </quartz> |
代码 8.5 所示的第二个 Job 文件与代码 8.4 的第一次相比只有稍稍不同。我们改变了 Job 所用来扫描的目录和触发计划。这里的重点就是在 Job 目录中你可以有多个 Job,而且 JobLoaderPlugin 将会加载它们并分别部署到 Scheduler 上。
本文链接 https://yanbin.blog/quartz-job-scheduling-framework-8/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。