总的来说,Jasper的自己主动检測实现的机制比較简单,依靠某后台线程不断检測JSP文件与编译后的class文件的最后改动时间是否同样,若同样则觉得没有改动。但倘若不同则须要又一次编译。实际上因为在Tomcat部署的项目的JSP可能引入了其它页面。或者引入了其它jar包,并且这些资源都可能是远程的资源,所以实际处理会比較复杂,同样要遍历检測这些引入的不同资源是否做了改动。

上图是一个形象的示意图。我们知道Tomcat架构中有四个级别的容器,Engine、Host、Context和Wrapper,而jsp编译相应在wrapper级别。所以通过StandardWrapper不断运行任务去调用jasper,而jasper则不断检測校验本地和远程的各种资源,一旦发现须要又一次编译则进行重编译。往下看看详细怎样实现。

首先,须要一个后台运行线程,Tomcat中有专门的一条线程处理不同容器的background任务。想在不同的容器中运行某些后台任务仅仅需重写backgroundProcess方法就可以实现。因为JspServlet相应于Wrapper级别。所以要在StandardWrapper中重写backgroundProcess。它会调用实现了PeriodicEventListener接口的Servlet,当中JspServlet就实现了PeriodicEventListener接口,此接口仅仅有一个periodicEvent方法。详细的检測逻辑在此方法中实现就可以。

其次,检測推断又一次编译的根据是什么?又一次编译就是再次把jsp变成java再变成class,而触发这个动作的条件就是当我们改动了某个jsp文件后,或者某jsp文件引入的资源被改动后。都将触发又一次编译动作。所以最好的推断根据就是某jsp或资源的最后改动时间lastmodified属性。正常顺序是jsp经过编译后生成class文件,把此class文件的lastmodified属性设置成jsp文件的lastmodified,此时两个文件的lastmodified属性是同样的,当我们改了jsp文件保存后,jsp的lastmodified属性就被置为当前时间。此时通过推断两个文件的lastmodified属性决定是否又一次编译。

又一次编译后jsp与class文件的lastmodified属性再次被置为同样。对于引入的资源。内存中维护了上次编译时引入资源的lastmodified属性,不断获取引入资源的lastmodified属性并与内存中相应的lastmodified属性进行比較,同样能够非常easy推断是否须要又一次编译。

最后,对于本地和远程资源分别怎样检測?对于本地资源来说。使用java.io.File类能够非常方便的实现对某JSP文件或其它文件的lastmodified属性读取。对于远程资源。比方jar包,为了方便处理jar包括的属性,使用java.net.URL能够非常方便操作,它包括了非常多协议,比如常见的jar、file、ftp等协议,使用相当方便,

URL includeUrl = new URL("jar:http://hostname/third.jar!/");

URLConnection iuc = includeUrl.openConnection();

long includeLastModified = ((JarURLConnection) iuc).getJarEntry().getTime();

仅仅需三步即完毕对远程jar包的读取且取出最后改动时间。当然URL还支持本地文件资源的读取,所以它是非常好的资源读取抽象对象。Tomcat中对引入资源的管理都是使用URL作为操作对象。

本小节探讨了Jasper自己主动检測机制的实现。自己主动检測机制给我们的开发带来了非常好的体验,我们不必自己改动了jsp后自己去运行编译操作。而是tomcat通过jasper帮我们定时检測编译操作。

点击订购作者《Tomcat内核设计剖析》

最新文章

  1. arcgis api for js入门开发系列五地图态势标绘(含源代码)
  2. ical4j 实现ICS文件的生成和解析
  3. 在VBA中调用excel函数
  4. 递推水题 Codeforces Round #289 (Div. 2, ACM ICPC Rules) A. Maximum in Table
  5. stsdb开发指南
  6. python文件选择:tkFileDialog 基础
  7. Oracle外键不加索引会引起死锁问题
  8. python: shutil模块 -拷贝文件
  9. Date日期比对
  10. webrtc 的回声抵消(aec、aecm)算法简介(转)
  11. cmd下运行PowerShell命令
  12. [转载]Sublime Text 2 - 性感无比的代码编辑器!程序员必备神器!跨平台支持Win/Mac/Linux
  13. 关于Debug下的Log打印问题
  14. 如何下载和编译Android4.0内核源代码goldfish(图像)
  15. 解决:Could not find debuginfo pkg for dependency package glibc-2.12-1.132.el6_5.3.i686
  16. IIS启用GZip压缩
  17. Java虚拟机之Java内存区域
  18. js生成带logo的二维码
  19. 微信小程序--地图组件与api-模拟器上返回的scale 与真机上不同--bindregionchange触发图标一直闪现问题
  20. FILESTREAM feature can't be enabled if you use cluster shared volumes

热门文章

  1. Inno Setup入门(二十五)——Inno Setup类参考(11)
  2. uboot如何检测XC2440是从Nand或Nor启动
  3. VMware虚拟机怎么从U盘启动
  4. Hibernate3的jar包
  5. sql server 判断及增加列的默认值约束
  6. vim配置python开发环境(转)
  7. log4j实现每一个线程保存一个日志文件
  8. Java中常用的6种排序算法详细分解
  9. 猜想:一组勾股数a^2+b^2=c^2中,a,b之一必为4的倍数。
  10. Office 如何双面打印Word文档