总的来说,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内核设计剖析》

jsp自己主动编译机制的更多相关文章

  1. jsp自动编译机制

    总的来说,Jasper的自动检测实现的机制比较简单,依靠某后台线程不断检测JSP文件与编译后的class文件的最后修改时间是否相同,若相同则认为没有改动,但倘若不同则需要重新编译.实际上由于在Tomc ...

  2. 浅谈java编译机制和运行机制

    源文件和字节码的组成方式 源文件: 拓展名后跟java的文件即java的源文件. Java 源码编译由以下三个过程组成: 1.分析和输入到符号表 2.注解处理 3.语义分析和生成class文件 流程图 ...

  3. 编译时和运行时、OC中对象的动态编译机制

    编译时 编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如Java只有JVM识别的字 ...

  4. JSP中的编译指令和动作指令的区别

    JSP中的编译指令和动作指令的区别 1.编译指令是通知Servlet引擎的处理消息,而动作指令只是运行时的脚本动作 2.编译指令是在将JSP编译成Servlet时起作用,而动作指令可替换成JSP脚本, ...

  5. angular编译机制

    转载https://segmentfault.com/a/1190000011562077 Angular编译机制 前言 http://www.cnblogs.com/ztwBlog/p/620975 ...

  6. Ant自己主动编译打包&公布 android项目

    Eclipse用起来尽管方便,可是编译打包android项目还是比較慢,尤其将应用打包公布到各个渠道时,用Eclipse手动打包各种渠道包就有点不切实际了,这时候我们用到Ant帮我们自己主动编译打包了 ...

  7. JSP中的编译指令和动作指令的差别

    JSP中的编译指令和动作指令的差别 1.编译指令是通知Servlet引擎的处理消息.而动作指令仅仅是执行时的脚本动作 2.编译指令是在将JSP编译成Servlet时起作用,而动作指令可替换成JSP脚本 ...

  8. 【Android】Eclipse自己主动编译NDK/JNI的三种方法

    [Android]Eclipse自己主动编译NDK/JNI的三种方法 SkySeraph Sep. 18th  2014 Email:skyseraph00@163.com 一.Eclipse关联cy ...

  9. OC的动态继承编译机制

    [问]为什么OC不能sizeof一个对象的大小或一个类的大小?和类结构相近的结构体却能够. [再问]为什么OC不能将对象声明到静态空间,如栈中?和类结构相近的结构体却能够. [答]由于OC的动态继承编 ...

随机推荐

  1. NOIP模拟·20141105题解

    [A.韩信点兵] 结论题+模板题,用到了中国剩余定理,维基百科上讲的就比较详细,这里就不再赘述了…… 对于这题,我们先利用中国剩余定理($x \equiv \sum{(a_i m_i (m_i^{-1 ...

  2. python2解决中文问题(无论是注释还是代码含有中文)

    interpreter:翻译器; 方式一:在第一行写上#coding=utf-8 方式二:在第一行写上#-*- coding:utf-8 -*-

  3. 九.Spring Boot JPAHibernateSpring Data

    1.项目结构 2.导入jar包 <!-- 添加Spring-data-jpa依赖. --> <dependency> <groupId>org.springfram ...

  4. iOS:时间格式化(标准时间转为时间戳、时间戳转为标准时间、时间戳转为日期)

    新建一个NSString(Time)分类,创建类方法实现时间的转换 .h文件 #import <Foundation/Foundation.h> @interface NSString ( ...

  5. 自定义标签(JspFragment类、invoke方法、开发带属性的标签)

    自定义标签(JspFragment类.invoke方法.开发带属性的标签) 一.JspFragment类 javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定 ...

  6. screen space shadowmap unity

    unity用到了screen space shadow map 1.camera 在light pos 生成depth1 2.screen space depth2 3.根据depth1 depth2 ...

  7. 摄像头模组 PDAF对焦(Phase Detection Auto Focus)

    本文主要是最近看的两个文档的总结,相对零散的笔记,包括<imx298 software reference PDAF>与<PDAF Truly>. 1.PDAF功能的实现需要使 ...

  8. 转: 学ppt的网址与素材

    转:http://www.jianshu.com/p/89b261e0b8f6 你说你要学ppt,可你知道这些吗?   之前身边的同学总说做PPT很难,每次做ppt都头疼,我都对此很不屑,直到前一段开 ...

  9. Android 常见内存泄漏的解决方式

    在Android程序开发中.当一个对象已经不须要再使用了,本该被回收时.而另外一个正在使用的对象持有它的引用从而导致它不能被回收.这就导致本该被回收的对象不能被回收而停留在堆内存中,内存泄漏就产生了. ...

  10. MySQL SELECT 语句

    SELECT语句: products表例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1eWluZ18xMDAx/font/5a6L5L2T ...