JSP 生命周期

jsp life cycle

什么是JSP生命周期?

JSP生命周期是指JSP页面被翻译成Servlet的过程,因为JSP页面需要先转换成Servlet才能处理服务请求。生命周期从JSP的创建开始,到其被销毁结束。

JSP生命周期的不同阶段

当浏览器请求一个JSP页面时,JSP引擎首先检查是否需要编译该页面。如果JSP页面是最后编译的,或者最近在JSP页面中进行了修改,那么JSP引擎就会编译该页面。

JSP页面的编译过程涉及三个步骤

  • JSP解析
  • 将JSP转换为Servlet
  • 编译Servlet

JSP生命周期图

JSP生命周期如下图所示。

JSP Life Cycle

以下步骤解释了JSP的生命周期

  1. JSP页面翻译
  2. JSP页面编译(JSP页面编译成_jsp.java)
  3. 类加载(_jsp.java被转换为类文件_jsp.class)
  4. 实例化(创建生成Servlet的对象)
  5. 初始化(容器调用_jspinit()方法)
  6. 请求处理(容器调用_jspservice()方法)
  7. 销毁(容器调用_jspDestroy()方法)

下面对上述各点进行更详细的总结。

1) JSP页面翻译

一个 Java Servlet 文件由一个 JSP 源文件生成。这是JSP生命周期的第一步。在翻译阶段,容器会验证JSP页面和标签文件的语法正确性。

  • JSP容器会解释标准指令和动作,以及引用标签库的自定义动作(这些都是JSP页面的一部分,将在后面的部分讨论)。
  • 在上图的描述中,demo.jsp在第一步被翻译成demo_jsp.java。
  • 让我们以“demo.jsp”为例,如下所示:

Demo.jsp

<html>
<head>
<title>Demo JSP</title>
</head>
<%
int demvar=0;%>
<body>
Count is:
<% Out.println(demovar++); %>
<body>
</html>

Demo.jsp的代码说明

代码行 1: html开始标签

代码行 2: Head标签

代码行 3-4: Title标签,即Demo JSP,以及关闭的head标签

代码行 5-6: 脚本let标签,在此初始化变量demo

代码行 7-8: 在body标签中,是要在输出中打印的文本(Count is: )

代码行 9: 脚本let标签,尝试打印变量demovar及其递增值

代码行 10-11: Body和HTML标签已关闭

Demo JSP页面在以下代码中转换为demo_jsp servlet。

JSP Life Cycle

Demo_jsp.java的代码说明

代码行 1: Servlet类demo_jsp继承自父类HttpServlet

代码行 2-3: 重写jsp的service方法,即_jspservice,它以HttpServletRequest和HttpServletResponse对象作为参数

代码行 4: 方法开始

代码行 5: 调用response对象的getWriter()方法获取PrintWriter对象(将对象的格式化表示打印到文本输出流)

代码行 6: 调用response对象的setContentType方法设置内容类型

代码行 7: 使用PrintWriter对象的write()方法尝试解析html

代码行 8: 初始化demovar变量为0

代码行 9: 调用PrintWriter对象的write()方法解析文本

代码行 10: 调用PrintWriter对象的print()方法将变量demovar从0递增到0+1=1。因此,输出将是1

代码行 11: 使用PrintWriter对象的write()方法尝试解析html

输出

JSP Life Cycle

  • 您可以在截图中看到,输出是1,因为demvar被初始化为0,然后递增到0+1=1。

在上面的示例中,

  • demo.jsp是一个初始化和递增变量的JSP。此JSP已转换为servlet(demo_jsp.class),其中JSP引擎加载JSP页面并将其转换为servlet内容。
  • 当转换发生时,所有模板文本都会被转换为println()语句,所有JSP元素都会被转换为Java代码。

这就是一个简单的JSP页面如何被翻译成一个servlet类。

2) JSP页面编译

  • 生成的java servlet文件被编译成java servlet类。
  • 从Java源页面到其实现类的翻译可以在JSP页面部署到容器和处理JSP页面之间的任何时间发生。
  • 在上图的描述中,demo_jsp.java被编译成类文件demo_jsp.class。

3) 类加载

  • 已从JSP源加载的Servlet类现在已加载到容器中。

4) 实例化

  • 在此步骤中,将生成类对象,即类的实例。
  • 容器在响应请求和其他事件时管理该类的一个或多个实例。通常,JSP容器是使用Servlet容器构建的。JSP容器是Servlet容器的扩展,因为两个容器都支持JSP和Servlet。
  • 容器提供的JSPPage接口提供了init()destroy()方法。
  • 有一个HttpJSPPage接口,用于服务HTTP请求,它还包含service方法。

5) 初始化

public void jspInit()
{
	//initializing the code
}
  • _jspinit()方法将初始化从JSP生成的Servlet实例,并在该阶段由容器调用。
  • 一旦实例创建完毕,init方法将立即被调用。
  • 此方法在JSP生命周期中仅调用一次,初始化方法声明如上所示。

6) 请求处理

void _jspservice(HttpServletRequest request HttpServletResponse response)
{
	//handling all request and responses
}
  • _jspservice()方法在JSP生命周期中由容器为JSP页面引发的所有请求调用。
  • 对于此阶段,它必须经历所有上述阶段,然后才能调用service方法。
  • 它传递请求和响应对象。
  • 此方法不能被重写。
  • 如上所示的方法:它负责生成所有HTTP方法,即GET、POST等。

7) 销毁

public void _jspdestroy()
{
            //all clean up code
}
  • _jspdestroy()方法也由容器调用。
  • 当容器决定不再需要Servlet实例来服务请求时,就会调用此方法。
  • 调用destroy方法后,Servlet就可以进行垃圾回收了。
  • 这是生命周期的结束。
  • 当我们需要执行任何清理操作时(例如释放数据库连接或关闭打开的文件),我们可以重写jspdestroy()方法。