日期:2014-05-16  浏览次数:20396 次

Tomcat7 的源码分析---JSP的编译(一)

?Tomcat7的JSP编译分析?

首先, 当一个jsp的请求发起后, 会由JspServlet进行接受(请求的流程会在后续文章里详细说明),? 会调用其service方法,? 解析获得该jsp的urlPath,? 并在参数中确定是否预编译模式.?

?之后, 调用serviceJspFile方法,?? 当该jsp是第一次请求时, 会新实例化JspServletWrapper对象,? 并将其加入JspRuntimeContext里.? 以后会直接从JspRuntimeContext中取JspServletWrapper对象, KEY值为jspUrl.

代码如下:



?

而后, 调用JspServletWrapper的service方法.?

?

?

?

?

以上就是jsp页面请求的流程. ?

觉得很奇怪吧, jsp的文件怎么就变成了servlet的class类了呢,????第一当然是将jsp变为java的源代码文件了.

?jsp怎么变成.java文件的呢?

在JspServletWrapper的service方法中调用ctxt.compile();?ctxt就是JspCompilationContext编译上下文

该方法主要做了以下几件事:

1.? 创建Compiler, 根据选项参数反射得到Compiler

???? tomcat7 提供使用Eclipse的JDT org.apache.jasper.compiler.JDTCompiler,?

???? 使用ANT的org.apache.jasper.compiler.AntCompiler

2. 移除旧的.java和.class文件.?

3.?将jsp文件转换生产.java

4.? 将生成的.java编译生成.class文件.

代码跟踪如下:

?

?

?

?以上代码来自tomcat源码类org.apache.jasper.compiler.Compiler

?

再跟进jspCompiler.compile();

?

?

?

?再次跟进String[] smap = generateJava();? 大家你一定很奇怪, 为什么结果是smap 呢?? 请大家耐心看下去吧.

这里就要简单介绍一下JSR-45

?? JSR-45(Debugging Support for Other Languages)为那些非 JAVA 语言写成,却需要编译成 JAVA 代码,运行在 JVM 中的程序,提供了一个进行调试的标准机制。也许字面的意思有点不好理解,什么算是非 JAVA 语言呢?其实 JSP 就是一个再好不过的例子,JSR-45 的样例就是一个 JSP。
  JSP的调试一直依赖于具体应用服务器的实现,没有一个统一的模式,JSR-45 针对这种情况,提供了一个标准的模式。我们知道,JAVA 的调试中,主要根据行号作为标志,进行定位。但是 JSP 被编译为 JAVA 代码之后,JAVA 行号与 JSP 行号无法一一对应,怎样解决呢?
  JSR-45 是这样规定的:JSP 被编译成 JAVA 代码时,同时生成一份 JSP 文件名和行号与 JAVA 行号之间的对应表(SMAP)。JVM 在接受到调试客户端请求后,可以根据这个对应表(SMAP),从 JSP 的行号转换到 JAVA 代码的行号;JVM 发出事件通知前, 也根据对应表(SMAP)进行转化,直接将 JSP 的文件名和行号通知调试客户端。

?

?当参数支持JSR-45则产生的smap就是jsp的行号与生产.java行号的对应关系.

?

?待续...

?

?

?