Quartz quartz.properties配置文件 java quartz 配置文件
3.声明式部署一个Job
前面我们讨论过,尽可能的用声明式处理软件配置,其次才才虑编程式。再来看代码3.6,如果我们要在Job启动之后改变它的执行时间和频度,必须去修改源代码重新编译。这种方式只适用于小的例子程序,但是对于一个大且复杂的系统,这就成了一个问题了。因此,假如能以声明式部署QuartJob时,并且也是需求允许的情况下,你应该每次都选择这种方式。
·配置quartz.properties文件
文件quartz.properties定义了Quartz应用运行时行为,还包含了许多能控制Quartz运转的属性。本章只会讲到它的基本配置;更多的高级设置将在以后讨论。在现阶段也不用太深入到每一项配置有效值的细节。
现在我们来看看最基础的quartz.properties文件,并讨论其中一些设置。代码3.7是一个修剪版的quartz.propertis文件。
注
Quartz框架会为几乎所有的这些属性设定默认值。
代码3.7.基本的QuartzProperties文件
#===============================================================
#ConfigureMainSchedulerProperties
#===============================================================
org.quartz.scheduler.instanceName=QuartzScheduler
org.quartz.scheduler.instanceId=AUTO
#===============================================================
#ConfigureThreadPool
#===============================================================
org.quartz.threadPool.threadCount=5
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
#===============================================================
#ConfigureJobStore
#===============================================================
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
#===============================================================
#ConfigurePlugins
#===============================================================
org.quartz.plugin.jobInitializer.class=
org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.overWriteExistingJobs=true
org.quartz.plugin.jobInitializer.failOnFileNotFound=true
org.quartz.plugin.jobInitializer.validating=false
#===============================================================
#ConfigureMainSchedulerProperties
#===============================================================
org.quartz.scheduler.instanceName=QuartzScheduler
org.quartz.scheduler.instanceId=AUTO
#===============================================================
#ConfigureThreadPool
#===============================================================
org.quartz.threadPool.threadCount=5
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
#===============================================================
#ConfigureJobStore
#===============================================================
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
#===============================================================
#ConfigurePlugins
#===============================================================
org.quartz.plugin.jobInitializer.class=
org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.overWriteExistingJobs=true
org.quartz.plugin.jobInitializer.failOnFileNotFound=true
org.quartz.plugin.jobInitializer.validating=false
在代码3.7所示的quartz.properties文件中,属性被逻辑上分为了四部分。属性在写法上无须要求分组或按特定的顺序。有#的行是注释行。
注
这里讨论的并没有涉及到所有可能的设置,仅仅是一些基本的设置。也是你需要去熟悉的,能使声明式例子运转起来的必须的设置项。quartz.properties中的所有属性配置将会分散在本书中的各章节中依据所在章节涉及内容详细讨论。
·调度器属性
第一部分有两行,分别设置调度器的实例名(instanceName)和实例ID(instanceId)。属性org.quartz.scheduler.instanceName可以是你喜欢的任何字符串。它用来在用到多个调度器区分特定的调度器实例。多个调度器通常用在集群环境中。(Quartz集群将会在第十一章,“Quartz集群”中讨论)。现在的话,设置如下的一个字符串就行:
org.quartz.scheduler.instanceName=QuartzScheduler
实际上,这也是当你没有该属性配置时的默认值。
代码3.7中显示的调度器的第二个属性是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,就像在代码3.7所做的那样。假如我们不希望在JVM退出之后丢失调度器的状态信息的话,我们可以使用关系型数据库来存储这些信息。这需要另一个作业存储(JobStore)实现,我们在后面将会讨论到。第五章“CronTrigger和其他”和第六章“作业存储和持久化”会提到你需要用到的不同类型的作业存储实现。
·插件配置
在这个简单的quartz.properties文件中最后一部分是你要用到的Quart插件的配置。插件常常在别的开源框架上使用到,比如Apache的Struts框架(见http://struts.apache.org)。
一个声明式扩框架的方法就是通过新加实现了org.quartz.spi.SchedulerPlugin接口的类。SchedulerPlugin接口中有给调度器调用的三个方法。
注
Quartz插件会在第八章“使用Quartz插件”中详细讨论
要在我们的例子中声明式配置调度器信息,我们会用到一个Quartz自带的叫做org.quartz.plugins.xml.JobInitializationPlugin的插件。
默认时,这个插件会在classpath中搜索名为quartz_jobs.xml的文件并从中加载Job和Trigger信息。
在下一节中讨论quartz_jobs.xml文件,这是我们所参考的非正式的Job定义文件。
注
默认时,插件JobInitializationPlugin在classpath中寻找quartz_jobs.xml文件。你可以覆盖相应设置强制这个插件使用不同的文件名查找。要做到这个,你必须设置上一节讨论的quartz.properties中的文件名。目前,我们就使用默认的文件名quartz_jobs.xml,至于如何修改quartz.properties中相应设置会在本章中后面讲到。
·使用quartz_jobx.xml文件
代码3.8就是目录扫描例子的Job定义的XML文件。正如代码3.5所示例子那样,这里我们用的是声明式途径来配置Job和Trigger信息的。
代码3.8.ScanDirectoryJob的quartz_jobs.xml
<?xmlversion='1.0'encoding='utf-8'?>
<quartz>
<job>
<job-detail>
<name>ScanDirectory</name>
<group>DEFAULT</group>
<description>
Ajobthatscansadirectoryforfiles
</description>
<job-class>
org.cavaness.quartzbook.chapter3.ScanDirectoryJob
</job-class>
<volatility>false</volatility>
<durability>false</durability>
<recover>false</recover>
<job-data-mapallows-transient-data="true">
<entry>
<key>SCAN_DIR</key>
<value>c:quartz-bookinput</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>2005-06-106:10:00PM</start-time>
<!--repeatindefinitelyevery10seconds-->
<repeat-count>-1</repeat-count>
<repeat-interval>10000</repeat-interval>
</simple>
</trigger>
</job>
</quartz>
<?xmlversion='1.0'encoding='utf-8'?>
<quartz>
<job>
<job-detail>
<name>ScanDirectory</name>
<group>DEFAULT</group>
<description>
Ajobthatscansadirectoryforfiles
</description>
<job-class>
org.cavaness.quartzbook.chapter3.ScanDirectoryJob
</job-class>
<volatility>false</volatility>
<durability>false</durability>
<recover>false</recover>
<job-data-mapallows-transient-data="true">
<entry>
<key>SCAN_DIR</key>
<value>c:quartz-bookinput</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>2005-06-106:10:00PM</start-time>
<!--repeatindefinitelyevery10seconds-->
<repeat-count>-1</repeat-count>
<repeat-interval>10000</repeat-interval>
</simple>
</trigger>
</job>
</quartz>
<job>元素描述了一个要注册到调度器上的Job,相当于我们在前面章节中使用scheduleJob()方法那样。你所看到的<job-detail>和<trigger>这两个元素就是我们在代码3.5中以编程式传递给方法schedulerJob()的参数。前面本质上是与这里一样的,只是现在用的是一种较流行声明的方式。你还可以对照着代码3.5中的例子来看在代码3.8中我们是如何设置SCAN_DIR属性到JobDataMap中的。
<trigger>元素也是非常直观的:它使用前面同样的属性,但更简单的建立一个SimpleTrigger。因此代码3.8仅仅是一种不同的(可论证的且更好的)方式做了代码3.5中同样的事情。显然,你也可以支持多个Job。在代码3.6中我们编程的方式那么做的,也能用声明的方式来支持。代码3.9显示了与代码3.6可比较的版本
代码3.9.你能在一个quartz_jobs.xml文件中指定多个Job
<?xmlversion='1.0'encoding='utf-8'?>
<quartz>
<job>
<job-detail>
<name>ScanDirectory1</name>
<group>DEFAULT</group>
<description>
Ajobthatscansadirectoryforfiles
</description>
<job-class>
org.cavaness.quartzbook.chapter3.ScanDirectoryJob
</job-class>
<volatility>false</volatility>
<durability>false</durability>
<recover>false</recover>
<job-data-mapallows-transient-data="true">
<entry>
<key>SCAN_DIR</key>
<value>c:quartz-bookinput1</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>2005-07-198:31:00PM</start-time>
<!--repeatindefinitelyevery10seconds-->
<repeat-count>-1</repeat-count>
<repeat-interval>10000</repeat-interval>
</simple>
</trigger>
</job>
<job>
<job-detail>
<name>ScanDirectory2</name>
<group>DEFAULT</group>
<description>
Ajobthatscansadirectoryforfiles
</description>
<job-class>
org.cavaness.quartzbook.chapter3.ScanDirectoryJob
</job-class>
<volatility>false</volatility>
<durability>false</durability>
<recover>false</recover>
<job-data-mapallows-transient-data="true">
<entry>
<key>SCAN_DIR</key>
<value>c:quartz-bookinput2</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>2005-06-106:10:00PM</start-time>
<!--repeatindefinitelyevery15seconds-->
<repeat-count>-1</repeat-count>
<repeat-interval>15000</repeat-interval>
</simple>
</trigger>
</job>
</quartz>
<?xmlversion='1.0'encoding='utf-8'?>
<quartz>
<job>
<job-detail>
<name>ScanDirectory1</name>
<group>DEFAULT</group>
<description>
Ajobthatscansadirectoryforfiles
</description>
<job-class>
org.cavaness.quartzbook.chapter3.ScanDirectoryJob
</job-class>
<volatility>false</volatility>
<durability>false</durability>
<recover>false</recover>
<job-data-mapallows-transient-data="true">
<entry>
<key>SCAN_DIR</key>
<value>c:quartz-bookinput1</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>2005-07-198:31:00PM</start-time>
<!--repeatindefinitelyevery10seconds-->
<repeat-count>-1</repeat-count>
<repeat-interval>10000</repeat-interval>
</simple>
</trigger>
</job>
<job>
<job-detail>
<name>ScanDirectory2</name>
<group>DEFAULT</group>
<description>
Ajobthatscansadirectoryforfiles
</description>
<job-class>
org.cavaness.quartzbook.chapter3.ScanDirectoryJob
</job-class>
<volatility>false</volatility>
<durability>false</durability>
<recover>false</recover>
<job-data-mapallows-transient-data="true">
<entry>
<key>SCAN_DIR</key>
<value>c:quartz-bookinput2</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>2005-06-106:10:00PM</start-time>
<!--repeatindefinitelyevery15seconds-->
<repeat-count>-1</repeat-count>
<repeat-interval>15000</repeat-interval>
</simple>
</trigger>
</job>
</quartz>
·为插件修改quartz.properties配置
在本章前面,告诉过你的是,JobInitializationPlugin找寻quartz_jobs.xml来获得声明的Job信息。假如你想改变这个文件名,你需要修改quartz.properties来告诉插件去加载那个文件。例如,假如你想要Quartz从名为my_quartz_jobs.xml的XML文件中加载Job信息,你不得不为插件指定这一文件名。代码3.10显示了怎么完成这个配置;我们现在是最后一次在这里重复说明这一插件部分。
代码3.10.为JobInitializationPlugin修改quartz.properties
org.quartz.plugin.jobInitializer.class=org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.fileName=my_quartz_jobs.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs=true
org.quartz.plugin.jobInitializer.validating=false
org.quartz.plugin.jobInitializer.overWriteExistingJobs=false
org.quartz.plugin.jobInitializer.failOnFileNotFound=true
org.quartz.plugin.jobInitializer.class=org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.fileName=my_quartz_jobs.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs=true
org.quartz.plugin.jobInitializer.validating=false
org.quartz.plugin.jobInitializer.overWriteExistingJobs=false
org.quartz.plugin.jobInitializer.failOnFileNotFound=true
在代码3.10中,我们添加了属性org.quartz.plugin.jobInitializer.fileName并设置该属性值为我们想要的文件名。这个文件名要对classloader可见,也就是说要在classpath下。
当Quartz启动后读取quartz.properties文件,然后初始化插件。它会传递上面配置的所有属性给插件,这时候插件也就得到通知去搜寻不同的文件。
译者后记:
想了又想,关于动词的“Schedule”还是选择“部署”,此前用的是“安排”,感觉不那么正式。当然英语中“部署”基本都用“Deploy”对应,平时与同事交流Quartz方面的技术都是说“往调度器上部署一个Job”的,只要词能达意就行。
对于“registerwiththeScheduler”,有时候是用的“通过调度器来注册”,有时候是“注册到调度器上”,意思基本一致的。
[/size]
更多阅读
Quartz quartz.properties配置文件 java quartz 配置文件
[size=medium]3.声明式部署一个Job前面我们讨论过,尽可能的用声明式处理软件配置,其次才才虑编程式。再来看代码3.6,如果我们要在Job启动之后改变它的执行时间和频度,必须去修改源代码重新编译。这种方式只适用于小的例子程序,但是对于一
SharePreference sharepreference崩溃
很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友。对于软件配置参数的保存,如果是window软件通常我们会采用ini文件进行保存,如果是j2se应用,我们会采用properties属
机密文件 英文 丐帮机密文件外泄
各丐帮基层组织负责同志: 最近北京有关部门根据地铁管理规定要求进行地铁内对我乞讨工作人员的清理活动,本组织高层领导紧急开会研究相应对策,以下决定请你们传达给基层乞讨工作人员,做好相关的学习贯彻工作: 一、地铁是
爱情保卫战折腾的爱 浏览器的折腾
虽然现在提倡“不折腾”,但我却老喜欢“折腾”,假如人活着不折腾的话,那怎么虚度光阴呢。昨晚下载了一些电子书,其中有一个名为《输赢》的文件,虽然这个文件是exe的,但我知道这是一个小说,最后还是勇敢地点了一下,不料书没打开却打开了一个
消毒餐具该收费吗 餐饮企业经营规范
餐饮企业经营规范 1范围 本标准规定了餐饮企业经营应具备的基本要求、经营场地、设备设施、规章制度、卫生安全和后续处理方面的要求。 本标准适用于各种经济类型的餐饮企业,包括饭庄、酒家、酒楼、餐馆、餐厅(含饭店、宾