Quartz快速入门指导
(作者 Dafydd James)
欢迎来到Quartz快速入门指导。阅读本指导,你可以看到下面的详细内容:
- 下载Quartz
- 安装Quartz
- 配置Quartz
- 启动一个简单的应用
在熟悉了Quartz Scheduler的基本功能之后,考虑更加高级的特性,例如企业级特性,允许作业jos和触发器trigger运行在特殊的Terracotta客户端上,而不是随机选择一个。
下载和安装Quartz
首先下载最新的稳定发布版,无需注册。解压下载的发布包,并安装它,这样你的应用就可以看见它。
Quartz JAR文件
Quartz包许多jar文件,位于发布包的根目录。Quartz的主要库都是以quartz-xxx.jar命名(xxx为版本号)。不管用Quartz的什么特性,这个jar包必须位于应用的类路径中。
一旦下载完Quartz,将可以将它解压到某个地方,取出quartz-xxx.jar包,并将其放在你想放的地方。
我主要在应用服务器环境中使用Quartz,我的偏好是将Quartz的jar包包含到我的企业级应用中(.ear或者.war文件)。然而,如果想要Quartz对于许多应用来说都是可用的,那么就确保它在你应用服务器的类路径中即可。如果你正在做一个独立的应用,将它和其它的依赖的jar包一起放在应用的类路径中。
Quartz依赖了许多第三方库(以jar包的形式),这些都包含在了发布包.zip文件的lib目录中。要使用Quartz的所有特性,这些jar包必须都在你的类路径中。如果要构建一个独立的Quartz应用,我建议你简单的把它们添加到类路径中。如果你在应用服务器环境中使用Quartz,至少某些jar包可能已经在类路径,所有I可以按需选择一些jar包。
在应用服务器环境中,当心当包含两个不同版本的相同的jar包时,会偶发一些奇怪的结果。例如,WebLogic包含J2EE的实现(在weblogic.jar内),它有可能与servlet.jar中的不一样。在这种情况下,通常最好将servlet.jar放在应用的外面,这样你就知道用正在使用哪个类了。
属性文件
Quartz使用属性文件quartz.properties。一开始这不是必须的,但是如果要使用一些基本配置,就必须把它放到类路径中了。
再次说明,演示示例是基于我个人的环境,我的应用是用WebLogic Workshop开发的。我将所有的配置文件都放在应用的根目录。当我打包到.ear文件时,配置工程也会打包成一个jar文件,也会包含到最终的.ear文件中。这就自动将quartz.properties放到了类路径中。
如果你正在构建一个包含Quartz的web应用,你可能想要将quartz.properties文件放到WEB-INF/classes文件夹下。
配置
这是个大问题!Quartz是一个可配置的应用。配置Quartz的最好方式就是编辑quartz.properties文件,并将它放到应用的类路径中。
在Quartz的发布包中有几个示例属性文件,位于examples/ directory目录。我建议你创建自己的quartz.properties文件,而不是复制示例中的某一个配置并删掉你不需的。这样更加整洁,你也可以探索一下Quartz能够提供什么。
属性的完整配置文档,请参考Quartz配置参考。
为了快速启动,基本的quartz.properties看起来可能是这样的:
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
这个配置创建的scheduler具有下面几个特点:
- org.quartz.scheduler.instanceName - 这个scheduler的名字为“MyScheduler”。
- org.quartz.threadPool.threadCount - 线程池中有3个线程,这意味着可以同时运行最多3个任务。
- org.quartz.jobStore.class - 所有的Quartz数据,例如任务的详细信息和触发器,都保存在内存里(而不是数据库中)。即使你有一个数据库,也想要在Quartz中用它,我建议你在你用数据库打开一个新的维度前让Quartz与RamJobStore一起工作。
启动一个简单的应用
现在,你下载并安装了Quartz,该让示例应用运行起来了。下面的代码获取了一个scheduler示例,把它启动起来,然后再把它关掉:
QuartzTest.java |
import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.impl.StdSchedulerFactory; import static org.quartz.JobBuilder.*; import static org.quartz.TriggerBuilder.*; import static org.quartz.SimpleScheduleBuilder.*;
public class QuartzTest {
public static void main(String[] args) {
try { // Grab the Scheduler instance from the Factory Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// and start it off scheduler.start();
scheduler.shutdown();
} catch (SchedulerException se) { se.printStackTrace(); } } } |
一旦你用StdSchedulerFactory.getDefaultScheduler()获得一个scheduler,你的应用就不会被终止,除非你调用了scheduler.shutdown()方法,因为可能会有活动的线程。
注意代码示例中的静态导入,这些会下面的代码中出现。
如果你没有设置日志,那么所有的日志都会被发送到控制台,你的输出类似于这样:
[INFO] 21 Jan 08:46:27.857 AM main [org.quartz.core.QuartzScheduler]
Quartz Scheduler v.2.0.0-SNAPSHOT created.
[INFO] 21 Jan 08:46:27.859 AM main [org.quartz.simpl.RAMJobStore]
RAMJobStore initialized.
[INFO] 21 Jan 08:46:27.865 AM main [org.quartz.core.QuartzScheduler]
Scheduler meta-data: Quartz Scheduler (v2.0.0) 'Scheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 50 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
[INFO] 21 Jan 08:46:27.865 AM main [org.quartz.impl.StdSchedulerFactory]
Quartz scheduler 'Scheduler' initialized from default resource file in Quartz package: 'quartz.properties'
[INFO] 21 Jan 08:46:27.866 AM main [org.quartz.impl.StdSchedulerFactory]
Quartz scheduler version: 2.0.0
[INFO] 21 Jan 08:46:27.866 AM main [org.quartz.core.QuartzScheduler]
Scheduler Scheduler_$_NON_CLUSTERED started.
[INFO] 21 Jan 08:46:27.866 AM main [org.quartz.core.QuartzScheduler]
Scheduler Scheduler_$_NON_CLUSTERED shutting down.
[INFO] 21 Jan 08:46:27.866 AM main [org.quartz.core.QuartzScheduler]
Scheduler Scheduler_$_NON_CLUSTERED paused.
[INFO] 21 Jan 08:46:27.867 AM main [org.quartz.core.QuartzScheduler]
Scheduler Scheduler_$_NON_CLUSTERED shutdown complete.
要实现一些感兴趣的事情,你只需在 start() 和 shutdown() 之间添加代码。
// 定义job,并绑定到HelloJob类上 JobDetail job = newJob(HelloJob.class) .withIdentity("job1", "group1") .build();
// 现在触发job运行,然后每40s重复一次 Trigger trigger = newTrigger() .withIdentity("trigger1", "group1") .startNow() .withSchedule(simpleSchedule() .withIntervalInSeconds(40) .repeatForever()) .build();
// 告诉quartz用我们的trigger来调度job scheduler.scheduleJob(job, trigger); |
(你也可能需要允许job被触发的时间,以及调用shutdown()之前的执行时间,对于这样简单的例子来说,你需要添加Thread.sleep(60000)即可)。
现在去玩一些有趣的!