Quartz Job Scheduling Framework[翻译]第十章. J2EE 中使用 Quartz (第二部分)

·在 J2EE 应用服务器中运行 Quartz

作为 J2EE 客户端运行 Quartz 比运行为外部 J2SE 应用程序稍显繁琐。这主要是因为部署一个应用到容器中有点了儿复杂,J2EE 规范对容器中的组件会有些约束。其中最大的原则之一就是涉及到该由谁来创建线程。因为 J2EE 容器有责任去管理所有资源,所以它并非允许谁想谁就能创建线程的。假如是这样的话,容器就会要更艰难的去管理环境和保证一切稳定性。Quartz 会创建自己的工作者线程,所以你必须依照一些步骤来保证它能正常的运转。

确保代像代码 10.1 那样的一个无状态会话 Bean 已部署到容器中。最简单的部署 Quartz 到容器中的方式是构建一个包含所必须文件的 WAR 包,然后使用管理工具或 Eclipse 部署这个 Web 应用到容器中。

这个 Web 应用的目录结构像其他任何 Web 应用是一样的。你必须添加以下文件至其中:

    ·web.xml (放置到 WEB-INF 下)

    ·quartz.properties (放置在 WEB-INF/classes 下)

    ·quartz_jobs.xml (放置在 WEB-INF/classes 下)

    ·Quartz 二进制包 (放置在 WEB-INF/lib 下)

    ·所需第三方包 (放置在 WEB-INF/lib 下)

因为正在构建一个 Web 应用,所以要加入一个必备的 web.xml 作为部署描述文件。代码10.4 中显示了我们要安装到容器中的客户端应用的 web.xml 文件。

代码 10.4. Quartz J2EE 客户端程序的 web.xml 文件

Quartz 框架包含有一个名为 QuartzInitializerServlet 的 Java Servlet,当被调用时它会初始化 Quartz 调度器并加载 Job 信息。在代码 10.4 中, 我们看到有设置 <load-on-startup> 标记值为 1,这指示着在容器启动的时候这个 servlet 会被自动加载并初始化。通过使用这个 servlet 去启动 Quartz 调度器,我们规避了容器中创建线程的约束,因为容器将允许 servlet 去创建用户线程的。

加入 QuartzInitializerListerner 到 Quartz 中
不久前,一个新的名为 QuartzInitializerListener 被加入到 Quartz 中来,它实现了 javax.servlet.ServletContextListener 接口。前面也有提过,这个类可用来替代 QuartzInitializerServlet 类。 

接下来,你需要把标准的 quartz.properties 文件放入到 Web 应用的 WEB-INF/classes 目录中去。在这里的这个文件没什么特别的;实质上,这一步与前面同类的操作是一样的。然而,我们这里使用到 JobInitializationPluin (这在第八章,"使用 Quartz 插件",它设计为从 XML 文件中加载 Job 信息)。默认情况下,这个插件查找一个叫做 quartz_jobs.xml 文件并从中加载所配置的 Job。如第八章描述的,使用这一特定的插件可以避免你写加载作业的代码,且在代码改变时不得不重新编译。quartz_jobs.xml 的内容如 代码 10.5 所示。

代码 10.5. J2EE 客户端所用的 quartz_jobs.xml 文件

你能看出在代码  10.5 中,我们仍然使用 EJBInvokerJob,只是声明在了  quartz_jobs.xml 文件中了。

quartz.properties 中指定插件
第八章已讲过,在使用 Quartz 插件就必须在 quartz.properties 文件中指定相应的插件信息。对于 JobInitialzationPluin,你必须在这个属性文件中加入下面一行代码:
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin

上面的文件都配置好后,就可以构建一个 WAR 文件并部署到你的容器中。当容器启动之后,就会加载那个 servlet 并初化,进而启动了调度器。调度器利用 JobInitializerPluin 去从 quartz_jobs.xml 文件中加载作业信息。自此,EJBInvokerJob 就会调用 EJB 上的 helloWorld() 方法了。

·包含 J2EE 客户端 JAR 包

在打包 J2EE 客户程序时,你需要把所需的特定于服务器的 J2EE 客户端 JAR 包打进来。针对不同的容器会有所不同,你需要参照具体文档予于决定。在构建一个独立运行的 Quartz 应用时,你还要加入所需的 Quartz 包。

二:使用  J2EE 容器的数据源

直到此刻,我们有意没去提到 JobStoresDataSources。在第六章,"作业存储和持久化",你已经学到可以把作业信息存储在内存中,或者假你需要作业信息在两次程序重启之间能持久保存下来,你就可以把作业信息存储到关系型数据库中。存在有两种类型的 JDBC 作业存储方式:

    ·JobStoreTX 在持久化操作过程中自己管理自己的事特

    ·JobStoreCMT 在持久化操作过程中技术容器管理事物(CMT)

如果你使用了 J2EE 容器并选择了上面的种类型的 JDBC JobStores,这时候你最好应该用容器提供的数据源。参考前面第六章,当在 J2EE 容器中使用 JDBC JobStores 时如何设置 quartz.properties 文件。

三:使用其他的 J2EE 资源

当部署 Quartz 到 J2EE 容器中,你可以利用  J2EE 组件可用的其他资源。例如,假如你需要发送 email,一种途径是得用 Quartz 的 SendMailJob,它依赖于 JavaMail。另一可用途径是,假如你把 Quartz 部署在容器中,能使用所有 J2EE 服务器都可提供的  mail session 资源,当然,前提是你在容器中已配置好的 mail session。那是作为 J2EE 客户端来部署 Quartz 好处之一。

四:EJB 2.1 规范:最后的曙光

在 EJB 2.1 的第 22 章中讨论到企业 JavaBean 的一个新的特性,定时器服务。这是一个容器管理的服务,给予需要基于时间事件的组件回调服务。实质上就是 EJB 能通过这一服务注册他们自己,当到了它们要执行的时间时就会接收到一个通知。定时器服务是被 EJB 容器实现并管理着的。现在还不知道 J2EE 厂商还要在那些规范后面加上多少功能。有些人争辩说 EJB 定时器的提议内容还不充分,同样的原因,java.util.Timer 类也不足以真正应付调度程序。最好也看看 EJB 的架构规范,可加入对框架的插件支持,例如 Quartz 就可以用来增强定时器服务的灵活性。

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

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

Subscribe
Notify of
guest

3 Comments
Inline Feedbacks
View all comments
BeanSoft
BeanSoft
16 years ago

谢谢分享了!

othello
othello
16 years ago

第4章怎么不译了,直接跳到第9章了。

隔叶黄莺
16 years ago

下面紧接着就会译第四章的,学以致用,工作中要用到前面所译章节内容,所以就先照顾了。自私一下,呵呵!