一、Servlet的生命周期
1、生命全过程
1)加载(加载servlet的class文件)
2)实例化(new servlet对象)
3)初始化(调用init(ServletConfig))
4)处理请求(service() doGet() doPost())
5)退出服务(destroy())
注意:整个过程只有一个servlet对象。
2、API中的过程
1)init() //只执行一次,在第一次初始化的时候
public void init(ServletConfig config)
throws ServletException
ServletConfig这个类封装了对servlet的配置信息,即web.xml中对于servlet进行配置的那部分信息。
2)service()
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
3)destroy()
//web项目退出的时候,会被调用
public void destroy()
二、测试
运行一个servlet,并且根据打印结果得知方法的调用顺序:
package com.hpe.servlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestLifeCycleServlet extends HttpServlet {
public TestLifeCycleServlet() {
System.out.println("constructor");
}
@Override
public void init(ServletConfig config)
throws ServletException {
System.out.println("init");
}
@Override
public void destroy() {
System.out.println("destory");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("doGet");
}
}
运行结果:
再次运行servlet,运行结果如下:
这说明构造方法和init方法在servlet第二次运行的时候都没有被调用,即该servlet对象只有一个,再次运行servlet时没有new新的servlet对象。
其实,JavaEE中要求servlet程序只能有一个servlet对象。
关闭服务器,打印destory,说明调用了destroy()方法。
总结:
①载入:第一次请求的时候被初始化,只一遍。
②初始化:调用init方法,只一遍。
③执行:每个请求,new一个新的线程,调用一遍service——super.service——doGet / doPost
a、不要在servlet中设计成员变量(多个请求线程共享,会发生资源冲突问题)
b、doGet,doPost常见异常:HTTP Status 405 - HTTP method POST(GET) is not supported by this URL:增加doGet()或doPost()方法即可。
④销毁:卸载前调用destroy方法,子类servlet一般不需要覆盖这个方法。
⑤在非分布的情况下,一个Servlet在服务器中通常只有一个实例。
一、关于init方法
可以在web.xml中将init方法配置为在启动服务器时就调用,即在启动服务器时就对servlet对象进行初始化。
将web.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>TestLifeCycleServlet</servlet-name>
<servlet-class>com.hpe.servlet.TestLifeCycleServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>TestLifeCycleServlet</servlet-name>
<url-pattern>/TestLifeCycleServlet</url-pattern>
</servlet-mapping>
</web-app>
可以看到在<servlet>标签中加了一行<load-on-startup>1</load-on-startup>,其中的"1"表示加载顺序。
此时重新启动服务器,如下图所示,可以看到提前构造方法和初始化方法在服务器启动完成之前就已经被调用,之后再手动运行servlet,发现不再调用init方法,只调用了service方法: