Quartz Job Scheduling Framework[翻译]第十三章. Quartz 和 Web 应用 (第三部分)

四. QuartzInitializerServlet 可谓救命草

Quartz 框架包括一个叫做 org.quartz.ee.servlet.QuartzInitializerServlet 的 Java 类,它继承自标准的 HttpServlet。你可应用这个 servlet 于你的 Web 应用中,它将会创建一个 StdSchedulerFactory 实例并在你的程序后续中一直可用。通常的,它就是做了命令行版本的 Quartz 程序的 main() 方法所做的事性。


QuartzInitializerServlet 在 Quartz 1.5 中有所改变
在 Quartz 的 1.5 发布版中,QuartzInitializerServlet 被修改为会存储 StdSchedulerFactory 实例到 Web 应用的 ServletContext 中。这就允许你的程序在任何地方都能访问到 Scheduler 实例,只要获取到了 HttpServletRequestHttpSession 对象,调用工厂的 getScheduler() 就访问到了 Scheduler 实例。

还新增了一个 start-scheduler-on-load 的 Servlet 初始化参数。这一参数指定 Scheduler 是否随 QuartzInitializerServlet 启动或是别处启动。假如未设置时默认为 True,Sheduler 将随 QuartzInitializerServlet 起来。否则,你的应用将不得不自己去获得 Scheduler 实例然后调用 start() 方法。

当容器加载 QuartzInitializerServlet,该 Servlet 的 init() 方法将被调用。这个 Servlet 读取几个初始化参数,创建 StdSchedulerFactory 类的实例,并使用指定(或默认) 的 Quartz 属性文件来初始化 Scheduler。

工厂创建之后,init() 方法就会决定 Scheduler 是否立即启动,或是让程序来决定何时启动它。代码 3.1 列出了 QuartzInitializerServletinit() 方法。

代码 13.1. QuartzIniializerServlet 类的 init() 方法

QuartzInitializerServlet 是 Quartz JAR 文件的一部分。只要你 Web 应用的 WEB-INF/lib 中有了 quartz.jar,这个 Servlet 在你的应用中就是可用的了。

·配置 Web 部署描述文件

Java Servlet 规范规定了每个 Web 应用都必须包含一个 Web 部署描述文件。部署文件(web.xml) 中包含了以下类型的信息:

    ·初始化参数

    ·Session 配置

    ·Servlet/JSP 定义

    ·Servlet/JSP 映射

    ·MIME 类型映射

    ·欢迎文件

    ·错误页面

    ·安全性

因为 QuartzInitializerServlet 是一个 Java Servlet,它必须配置到部署描述文件中让容器来加载它。代码 13.2 描绘了怎样在 web.xml 文件中配置 QuartzInitializerServlet。

代码 13.2. QuartzInitializerServlet 需要对 web.xml 文件作相应的修改

QuartzInitializerServlet 支持三个 Quartz 规范的初始化参数

初始化参数 config-file

config-file 参数用来指定 Quartz 属性文件的路径和文件名。StdSchedulerFactory 使用这个文件配置 Scheduler 实例。这个参数是可选的;假如未指定,就会用默认的 quartz.properties 文件。使用此参数最简单的方式(假定你想提供自己的属性文件) 是把你的属性文件放到 WEB-INF/classes 目录中,然后如下方式指定 init-param:

初始化参数 shutdown-on-unload

shutdown-on-unload 参数用于在容器卸载本 Servlet 时引起 scheduler.shutdown() 方法的调用。一个容器在关闭,或某种条件时,在一个热部署环境中重新加载时就会卸载这个 Servlet。这个参数是可选的,默认值是 true

初始化参数 start-scheduler-on-load

start-scheduler-on-load 参数用于告诉 Servlet 调用 Scheduler 实例的 start() 方法。假如它没有启动,Scheduler 就需要由程序在晚些时候来启动,在 start() 未被调用之前是不会有 Job 运行的。这一参数是可选的,如果未指定时默认为 true。这个参数是在 1.5 发行版中加载来,不存在于早期版本中。

·访问 SchedulerFactory 和 Scheduler

自 Quartz 1.5 开始,QuartzInitializerservlet 将自动将 StdSchedulerFactory 实例以某一预定义键存放于 ServletContext 中。

早期 Quartz 版本中的 QuartzInitializerServlet

QuartzInitializerServlet 在早期版本的框架中就出现了。在以往版本中,StdSchedulerFactory 不会存放到 ServletContext 中。Sheduler 在 Servlet 的 init() 方法中初始化后即启动。欲从你的代码中获取 Scheduler 实例,你必须使用 StdSchedulerFactory 的某个 get 方法访问该 Servlet  创建的 Scheduler。从 ServletContext 中访问 Scheduler 的改变是在 1.5 版中加进来的。

你可在代码 13.1 的 init() 方法结束部分看出来。一旦工厂被存入 ServletContext,有多种方式可以获取访问到它。最简单的方式,尤其是你在用 Struts 框架的时候,是使用 request 对象。代码 13.3 展示了一个 Struts Action 类,叫做 StartSchedulerAction。当这个 Action 被调用(假定是通过 /startscheduler.do 这样的 URL 来访问),SchedulerFactory 就能获取取,接着可以调用 getScheduler() 方法。

代码 13.3. SchedulerFactory 和 Scheduler 能简单的被访问

当从 SchedulerFactory 获取到 Scheduler 之后,你就可以按正常方式般调用 Scheduler 实例的方法。在代码 13.3 中,Scheduler 是使用 start() 方法来启动的,这是你所习惯的。

StdSchedulerFactory 存于 ServletContext 中的优点是避免了你重复创建它。实际上,你可以使得访问 Scheduler 甚至更简单,做法是把所有访问 ServletContext 和创建 Scheduler 的逻辑放到一个工具类中。代码 13.4 展示了这样一个名为 ActionUtil 的类,它简化了获得一个 Scheduler 对象的引用。

代码 13.4. ActionUtil 类方便了访问 Scheduler

你能使用 ActionUtil.getScheduler() 方法很方便的获取到 Scheduler 实例。代码 13.3 中接下来的片断就是类 StartSchedulerAction 如何使用 Action.getScheduler() 方法了:

代码 13.4 中的 ActionUtil 并非 Quartz 框架的一部份,但它或许会被加入到将来的版本中。你可在你的应用中需要的时候加入相同的东西。

本文链接 https://yanbin.blog/quartz-job-scheduling-framework-13-3/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

2 Comments
Inline Feedbacks
View all comments
隔叶黄莺
15 years ago

org.cavaness.jobconsole.web.QuartzFactoryServlet

这只是说的一个虚拟的 Job Console 的项目中,假定为自己实现的一个 QuartzFactoryServlet 类,旨在启用 Web 应用时初始化一个 SchedulerFactory 放在 ServletContext 中。原文并未对它进它进行深入,所以你可以自己去实现它;或者不用去理会它,这里只用了 QuartzFactoryServlet.QUARTZ_FACTORY_KEY 这么一个常,为的是以此键把 ScehdulerFactory 放在 ServletContext 中,方便应用随时取用。

黑骑士
黑骑士
15 years ago

哦,这样呀,谢谢了,再研究研究