第八章. 使用 Quartz 插件
Quartz 框架提供了几种用于扩展平台能力的方式。通过使用各种 "钩子" (通常指的就是扩展点),Quartz 变得很容易被扩展和定制化来适应你的需要。其中一个最简单的扩展框架的方法就是使用 Quartz 插件。本章就来看看如何使用插件机制让 Quartz 进入到之前 Quartz 用户没去过的领域。
一. 什么是插件?
假如你使用过其他的开源框架,例如 Apache Struts,你应该已经熟悉了插件的概念和它们的用法。非常简单,一个 Quartz 插件就是一个实现了 org.quartz.spi.SchedulerPlugin 接口的 Java 类,并且被作为插件注册给了 Scheduler。这个插件接口包含了三个方法,显示在代码 8.1 中。 Read More
开门见山把产生问题的原因的解决办法列出来。
我们一般获取 Statement 都是通过 conn.createStatement() 方法,很少传递参数给它的,所以其内置属性都取默认值的,取记录只用 while(rs.next()) 逐个取即可。然而有一个需求(Oracle 8i 之前的版本不支持子查询排序,所以无法用 rownum 取分页记录) 是通过如下代码来得到 Statement:
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
由它获得的结果集可以 rs.absolute(n) 直接跳到第 n 行记录来获得值,但就这个用法出问题了,取出来的中文出现乱码了,如 "无效",变成了 "0xE697A0E69588" Read More
八. 监听器中的线程使用
你看到了监听器接口中的方法后,你或许想知道是线程在调用监听器方法中饰演着什么样的角色。基实监听器方法是存在一个时序的,正如你看到方法名能想像到的那样。在一个 Job 执行的生命周期中,调用监听器方法以的顺序通常是固定的。图 7.2 描绘了监听方法的调用顺序和所涉及到的工作者线程。图 7.2. 监听器方法按某一特定的时序被调用
调用监听器方法的时序是固定的。如图 7.2 所示,在 Job 的执行前后,调用 Job 的 execute() 方法相同的线程被用于调用 JobListener 和 TriggerListener 的方法。假如你使用任何类类型的第三方线程管理工具或者打算实现你自己的线程池管理,知道这一点是很重要的。假如你在监听方法中实现了一个长运行逻辑时,这也会带来对性能上的负面影响。因为调用监听方法的线程和执行 Job 是同一个工作者线程,你不应该把监听方法实现的太复杂并要花费较长时间才能完成。保持它们的执行时间尽可能短。
Read More
七. 在 quartz_jobs.xml 文件中实现监听器
本章的所有例子告诉了你如何以编程的方式设置监听器。假如我们一个关于在 quartz_jobs.xml 文件中以声明式配置监听器的例子都不提供本章就不能算是完结。
自 Quartz 1.5 开始,你能够在 Job 定义文件中指定监听器,当然就是知名的 quartz_jobs.xml 文件了。代码 7.14 显示了一个使用全局监听器的例子。
代码 7.14. Quartz 监听器能在 quartz_jobs.xml 文件中实现 Read More
六. 使用 FileScanListener
Quartz 框架还包含一个我们未曾提及的监听器。这个监听器不像别的,因为它是为特定目的而设计的:同框架所带的一个工具 Job 一起用的。
这个监听器就是 org.quartz.jobs.FileScanListener 接口,它显式的设计为 FileScanJob 所用的,这一 Job 也在 org.quartz.jobs 包中。FileScanJob 检查某一指定文件的 lastModifiedDate。当某人改变了这个文件,这个 Job 就调用 FileScanListener 的 fileUpdated() 方法。
就像使用其他类型的 Quartz 监听器一样,你必须创建一个实现了 FileScanListener 接口的具体类。只有一个方法需要实现: Read More- 五. 监听 Scheduler 事件
org.quartz.SchedulerListener 接口包含了一系列的回调方法,它们会在 Scheduler 的生命周期中有关键事件发生时被调用。代码 7.9 列出了包括在 SchedulerListener 接口的方法。
代码 7.9. org.quartz.SchedulerListener 接口中的方法1public interface SchedulerListener { 2 public void jobScheduled(Trigger trigger); 3 public void jobUnscheduled(String triggerName, String triggerGroup); 4 public void triggerFinalized(Trigger trigger); 5 public void triggersPaused(String triggerName, String triggerGroup); 6 public void triggersResumed(String triggerName,String triggerGroup); 7 public void jobsPaused(String jobName, String jobGroup); 8 public void jobsResumed(String jobName, String jobGroup); 9 public void schedulerError(String msg, SchedulerException cause); 10 public void schedulerShutdown(); 11}
Read More
Tomcat 启动时的系统日志默认是由 JdkLog14Logger 打印出来的,如
2008-7-7 11:19:34 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/5.0.28
2008-7-7 11:19:34 org.apache.catalina.core.StandardHost start
信息: XML validation disabled
2008-7-7 11:19:34 org.apache.catalina.core.StandardHost getDeployer
信息: Create Host deployer for direct deployment ( non-jmx )
那我们能不能用 Log4J 来输出这种系统日志呢?我们知道像 Apache 那样的大部分开源框架、组件都是用通用日志组件 (commons-logging) 来输出日志的,因此如果把 commons-logging 和 log4j 搭配使用就能输出十分详尽的日志信息。 Read More
四. 监听 Trigger 事件
正如 JobListener, org.quartz.TriggerListener 接口也包含一系列给 Scheduler 调用的方法。然而,与 JobListener 有所不同的是, TriggerListener 接口还有关于 Trigger 实例生命周期的方法。代码 7.5 列出了 TriggerListener 接口的方法。
代码 7.5. org.quartz.TriggerListener 接口的方法 Read More- 魔高一尺,道应比其高一丈┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│ ┆ ┆ ┆乃┆,┆四┆星┆瓦┆作┆。┆以┆天┆燎┆瓮┆言┆天┆ │
│ ┆ ┆ ┆作┆吞┆夷┆文┆安┆“┆士┆万┆下┆原┆安┆封┆涯┆ │
│ ┆ ┆ ┆此┆吐┆闻┆竖┆县┆不┆民┆计┆异┆之┆案┆事┆,┆红│
│ ┆ ┆ ┆妇┆天┆而┆排┆”┆贱┆交┆,┆己┆势┆,┆者┆红┆朝│
│ ┆ ┆ ┆人┆地┆轻┆体┆。┆省┆语┆禁┆者┆,┆传┆二┆朝┆笑│
│ ┆ ┆ ┆小┆,┆之┆属┆时┆”┆作┆“┆,┆乃┆之┆十┆之┆话│
│ ┆ ┆ ┆子┆包┆,┆文┆文┆,┆书┆贵┆天┆差┆海┆万┆稷┆一│ Read MoreOracle SQL的优化规则:- 尽量少用IN操作符,基本上所有的IN操作符都可以用EXISTS代替
用IN写出来的SQL的优点是比较容易写及清晰易懂,但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:
ORACLE 试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用 IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。 Read More