Servlet的生命流程
- 2021-02-01
Servlet 生命周期
Servlet 运行在 Servlet 容器中,没有main函数
Servlet 生命周期可被定义为从创建直到毁灭的整个过程
Servlet 初始化后调用 init () 方法。
Servlet 调用 service() 方法来处理客户端的请求。
Servlet 销毁前调用 destroy() 方法。
最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
1. init方法:
init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化。
Servlet[interface] 中声明了方法init()。
GenericServlet[class] 实现了接口Servlet实现了方法init(), 并且重载了函数init(ServletConfig)。
HttpServlet[class] 继承于GenericServlet, 没有重写init()。
我们编写类 ExpServlet 继承于 HttpServlet[class], 重写了init、init(ServletConfig)。
实验结果:
在重写了init(ServletConfig)将调用init(ServletConfig), 否则调用init()。
2. service方法
service()方法是执行实际任务的主要方法。Servlet 容器调用 service() 方法来处理来自客户端的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
Servlet[interface] 中声明了方法 service(ServletRequest req, ServletResponse res)。
GenericServlet[class] 没有了实现接口Servlet的方法service(ServletRequest req, ServletResponse res)。
HttpServlet[class] 继承于GenericServlet, 实现了service(ServletRequest req, ServletResponse res), 并且重载了service(HttpServletRequest, HttpServletResponse)。service(ServletRequest req, ServletResponse res)主要是将req由ServletRequest类型强转为HttpServletRequest, res由ServletResponse类型强转为HttpServletResponse。然后调用 service(HttpServletRequest, HttpServletResponse), 该函数检查Http类型,调用对应的方法
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
this.service(request, response);
}
我们编写类 ExpServlet 继承于 HttpServlet[class], 重写了service(ServletRequest req, ServletResponse res)、service(HttpServletRequest, HttpServletResponse)。
实验结果:
每次请求打开一个新的线程,都会调用service(ServletRequest req, ServletResponse res),然后 service(ServletRequest req, ServletResponse res)调用service(HttpServletRequest, HttpServletResponse)运行。
3. destroy方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
实验结果:
destory在结束的时候被主线程调用。
测试代码
package com.chrisjaunes.base_exp;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Logger;
/**
* 本实验用于了解 servlet 的流程
* @author ChrisJaunes
*/
@WebServlet(name = "Exp1Servlet", urlPatterns = "/Exp1")
public class Exp1Servlet extends HttpServlet {
private final Logger logger = Logger.getLogger("Exp1Servlet");
@Override
public void init() throws ServletException {
logger.info("init " + Thread.currentThread());
super.init();
}
// @Override
// public void init(ServletConfig config) throws ServletException{
// logger.info("init_ServletConfig " + Thread.currentThread());
// super.init();
// }
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
logger.info("service_ServletRequest_ServletResponse " + Thread.currentThread());
super.service(req, res);
}
@Override
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{
logger.info("service_HttpServletRequest_HttpServletResponse " + Thread.currentThread());
super.service(req, res);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
logger.info("doPost_HttpServletRequest_HttpServletResponse " + Thread.currentThread());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
logger.info("doGet_HttpServletRequest_HttpServletResponse " + Thread.currentThread());
}
@Override
public void destroy(){
logger.info("destroy " + Thread.currentThread());
super.destroy();
}
}
测试结果
27-Feb-2021 01:01:25.106 信息 [http-nio-8080-exec-7] com.chrisjaunes.base_exp.Exp1Servlet.init init Thread[http-nio-8080-exec-7,5,main]
27-Feb-2021 01:01:25.108 信息 [http-nio-8080-exec-7] com.chrisjaunes.base_exp.Exp1Servlet.service service_ServletRequest_ServletResponse Thread[http-nio-8080-exec-7,5,main]
27-Feb-2021 01:01:25.109 信息 [http-nio-8080-exec-7] com.chrisjaunes.base_exp.Exp1Servlet.service service_HttpServletRequest_HttpServletResponse Thread[http-nio-8080-exec-7,5,main]
27-Feb-2021 01:01:25.109 信息 [http-nio-8080-exec-7] com.chrisjaunes.base_exp.Exp1Servlet.doGet doGet_HttpServletRequest_HttpServletResponse Thread[http-nio-8080-exec-7,5,main]
27-Feb-2021 01:01:26.968 信息 [http-nio-8080-exec-8] com.chrisjaunes.base_exp.Exp1Servlet.service service_ServletRequest_ServletResponse Thread[http-nio-8080-exec-8,5,main]
27-Feb-2021 01:01:26.968 信息 [http-nio-8080-exec-8] com.chrisjaunes.base_exp.Exp1Servlet.service service_HttpServletRequest_HttpServletResponse Thread[http-nio-8080-exec-8,5,main]
27-Feb-2021 01:01:26.969 信息 [http-nio-8080-exec-8] com.chrisjaunes.base_exp.Exp1Servlet.doGet doGet_HttpServletRequest_HttpServletResponse Thread[http-nio-8080-exec-8,5,main]
27-Feb-2021 01:04:27.428 信息 [main] com.chrisjaunes.base_exp.Exp1Servlet.destroy destroy Thread[main,5,main]