WEB容器JSP页面的访问请求时,它将把该访问请求交给JSP引擎去处理。Tomcat中的JSP引擎就是一个Servlet程序,它负责解释和执行JSP页面。

第一次请求:当服务器上的一个JSP页面被第一次请求执行时,服务器上的JSP引擎首先将JSP页面文件转译成一个.java文件,也就是servlet源程序,接着再把这个Servlet源程序编译这个java文件生成.class的字节码文件(对于Tomcat,生成的class文件默认情况下存放在<Tomcat>/work目录下),然后执行字节码文件响应客户端的请求。

再次请求:JSP引擎将直接执行字节码文件来响应客户。

 

即:

①客户端发出请求。

②Web容器将JSP转译成Servlet源代码。

③Web容器将产生的源代码进行编译。

④Web容器加载编译后的代码并执行。

⑤把执行结果响应至客户端。

jsp页面代码 java 代码执行顺序 jsp页面执行过程_字节码

在执行 JSP 网页时,通常可分为两个时期:转译时期(TranslationTime)和请求时期(Request Time)

  • 转译时期:JSP网页转译成Servlet类。
  • 请求时期:Servlet类执行后,响应结果至客户端。 

注:将JSP网页转译为 Servlet源代码(.java),此段称为转译时期(Translation time);将Servlet源代码(.java)编译成 Servlet 类(.class),此段称为编译时期(Compilation time)。

 

 

接下来我们看每一步的具体实现:


①客户端请求jsp文件,web服务器(tomcat等)根据jsp文件生成java文件:

jsp页面代码 java 代码执行顺序 jsp页面执行过程_java文件_02

②java文件生成对应的class字节码文件,字节码文件是可以通过class loader加载进虚拟机的:

jsp页面代码 java 代码执行顺序 jsp页面执行过程_java文件_03

③  web容器加载class字节码文件:

jsp页面代码 java 代码执行顺序 jsp页面执行过程_字节码_04

④  web容器通过反射等手段建立hello_jsp实例:

jsp页面代码 java 代码执行顺序 jsp页面执行过程_jsp页面代码 java 代码执行顺序_05

⑤  调用对应的jspInit来进行实例初始化:

jsp页面代码 java 代码执行顺序 jsp页面执行过程_字节码_06

⑥  调用_jspservice,响应用户请求:

jsp页面代码 java 代码执行顺序 jsp页面执行过程_java文件_07

⑦  调用jspDestroy销毁jsp_hello实例:

jsp页面代码 java 代码执行顺序 jsp页面执行过程_jsp页面代码 java 代码执行顺序_08

因为jsp_hello继承自HttpJspBase,HttpJspBase又继承自Servlet,所以jsp_hello是个servlet,其生命周期可以交由web服务器控制。

 

举实例来解释:


用户在浏览器地址栏上输入http://localhost:8080/dage/index.jsp,web服务器判断用户请求的资源是dage应用中的index.jsp页面,web服务器在dage应用中找到index.jsp,启动JSP翻译引擎,将index.jsp翻译成index_jsp.java文件,并且将index_jsp.java文件编译生成index_jsp.class字节码文件,将其存储在Tomcat服务器work目录中。index_jsp.class类继承了HttpJspBase,HttpJspBase继承了HttpServlet,所以JSP本质上就是Servlet,和Servlet完全相同。只有用户第一次访问这个JSP或者JSP页面被修改了,才会重新翻译。JSP有三个阶段:翻译(一次),编译(一次),运行(多次)。JSP更改,不需要重启服务器,也不需要重新部署项目。

Jsp和Servlet本质上没有区别,但是JSP和Servlet它们的主要职责是有区别的:JSP主要是提取数据做页面展示,而Servlet主要完成业务逻辑处理以及资源跳转。Servlet是Controller(控制层),JSP是View(展示层)。项目开发中只使用JSP也可以完成开发,因为JSP最终也是一个java类,可以在JSP中编写JDBC等其他程序,但是这样做就违背了设计原则,我们要把的主要职责凸显出来,它的弱点我们还是要尽量避让的。(JSP和Servlet都是单实例多线程的环境下运行的,JSP和Servlet中出现的实例变量、静态变量都会存在线程安全问题。)