Servlet的生命周期
在Java中,任何对象都有生命周期,Servlet也不例外,接下来,通过一张图来描述Servlet的生命周期,如图1所示。
图1 Servlet的生命周期
图1描述了Servlet的生命周期。按照功能的不同,大致可以将Servlet的生命周期分为三个阶段,分别是初始化阶段、运行阶段和销毁阶段。接下来,针对Servlet生命周期的这三个阶段进行详细地讲解,具体如下:
● 初始化阶段
当客户端向Servlet容器发出HTTP请求要求访问Servlet时,Servlet容器首先会解析请求,检查内存中是否已经有了该Serlvet对象,如果有直接使用该Serlvet对象,如果没有就创建Servlet实例对象,然后通过调用init()方法实现Servlet的初始化工作。需要注意的是,在Servlet的整个生命周期内,它的init()方法只被调用一次。
● 运行阶段
这是Servlet生命周期中最重要的阶段,在这个阶段,Servlet容器会为这个请求创建代表HTTP请求的ServletRequest对象和代表HTTP响应的ServletResponse对象,然后将它们作为参数传递给Servlet的service()方法。service()方法从ServletRequest对象中获得客户请求信息并处理该请求,通过ServletResponse对象生成响应结果。在Servlet的整个生命周期内,对于Servlet的每一次访问请求,Servlet容器都会调用一次Servlet的service()方法,并且创建新的ServletRequest和ServletResponse对象,也就是说,service()方法在Servlet的整个生命周期中会被调用多次。
● 销毁阶段
当服务器关闭或web应用被移除出容器时,Serlvet随着web应用的销毁而销毁。在销毁Servlet之前,Servlet容器会调用Servlet的destroy()方法,以便让Servlet对象释放它所占用的资源。在Servlet的整个生命周期中,destroy()方法也只被调用一次。需要注意的是,Servlet对象一旦创建就会驻留在内存中等待客户端的访问,直到服务器关闭,或web应用被移除出容器时Servlet对象才会销毁。
接下来,通过一个具体的案例来演示Servlet生命周期方法的执行效果。在HelloWorldServlet中重写init()方法和destroy()方法,代码如例1所示。
例1 HelloWorldServlet.java
1 package cn.itcast.firstapp.servlet;
2 import javax.servlet.*;
3 public class HelloWorldServlet extends GenericServlet {
4 public void init(ServletConfig config) throws ServletException {
5 System.out.println("init methed is called");
6 }
7 public void service(ServletRequest request, ServletResponse
response)
8 throws ServletException {
9 System.out.println("Hello World");
10 }
11 public void destroy() {
12 System.out.println("destroy method is called");
13 }
14 }
重新编译HelloWorldServlet.java文件,将编译后生成的class文件拷贝到chapter04的WEB-INF/classes目录。启动Tomcat服务器,在浏览器的地址栏输入URL地址http://localhost:8080/firstapp/helloWorldServlet
访问helloWorldServlet,Tomcat控制台的打印结果如图2所示。
图2 运行结果
从图2可以看出,Tomcat的控制台输出了“init methed is called”和“Hello World”语句。说明用户第一次访问HelloWorldServlet时,Tomcat就创建了HelloWorldServlet对象,并在调用service()方法处理用户请求之前,通过init()方法实现了Servlet的初始化。
刷新浏览器,多次访问HelloWorldServlet,Tomcat控制台的打印结果如图3所示。
图3 运行结果
从图3中可以看出,Tomcat控制台只会输出“Hello World”语句。由此可见,init()方法只在第一次访问时执行,service()方法则在每次访问时都被执行。
如果想将HelloWorldServlet移除,可以通过Tomcat的管理平台终止Web应用chapter04,此时,Servlet容器会调用HelloWorldServlet的destroy()方法,在Tomcat控制台打印出“destroy method is called”语句,如图4所示。
图4 运行结果
&多学一招: 自动加载Servlet程序
有时候,我们希望某些Servlet程序可以在Tomcat启动时随即启动。例如,当启动一个Web项目时,首先需要对数据库信息进行初始化。这时,我们只需要使用web.xml文件中<load-on-startup>元素,将初始化数据库的Servlet配置为随着web应用启动而启动的Servlet即可。
<load-on-startup>元素是<servlet>元素的一个子元素,它用于指定Servlet被加载的时机和顺序。在<load-on-startup>元素中,其值必须是一个整数。如果这个值是一个负数,或者没有设定这个元素,Servlet容器将在客户端首次请求这个Servlet时加载它;如果这个值是正整数或0,Servlet容器将在Web应用启动时加载并初始化Servlet,并且<load-on-startup>的值越小,它对应的Servlet就越先被加载。
接下来,将例2中HelloWorldServlet配置为Tomcat启动时自动加载的Servlet,具体配置方式如下所示:
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>cn.itcast.firstapp.servlet.HelloWorldServlet</servlet-class>
<!--设置Servlet在Web应用启动时初始化-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/helloWorldServlet</url-pattern>
</servlet-mapping>
启动Tomcat服务器,在Tomcat控制台输出的信息中,会发现如图5所示的内容。
图5 运行结果
从图5中可以看出,HelloWorldServlet的初始化信息被打印了出来,由此说明,HelloWorldServlet在Tomcat启动时就被自动加载并且初始化了。