serlvet生命周期应该是java web方向面试必考的问题吧!
一、从API文档来看
Defines methods that all servlets must implement.
A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
一个servlet是在web服务器上运行的小java程序。serlvets接收和响应来自客户端的请求,通常使用HTTP协议(超文本传输协议)。
To implement this interface, you can write a generic servlet that extends javax.servlet.GenericServlet
or an HTTP servlet that extends javax.servlet.http.HttpServlet
.
你可以通过写一个继承 javax.servlet.GenericServlet 一般的servlet
或者继承 javax.servlet.http.HttpServlet
的HTTP servlet来实现该接口。
This interface defines methods to initialize a servlet, to service requests, and to remove a servlet from the server. These are known as life-cycle methods and are called in the following sequence:
该接口定义了初始化servlet,请求服务和从服务器移除servlet的一些方法。这些方法被称为是生命周期方法并且按照以下顺序被调用:
init
method.
service
method are handled.
destroy
method, then garbage collected and finalized.
In addition to the life-cycle methods, this interface provides the getServletConfig
method, which the servlet can use to get any startup information, and the getServletInfo
method, which allows the servlet to return basic information about itself, such as author, version, and copyright.
除生命周期方法之外,接口提供了getServletConfig
方法获取启动信息和getServletInfo
方法来允许servlet返回自身基本信息,如作者、版本、版权。
从说明可看出servlet整个生命周期包含初始化阶段(调用init方法)、接收和响应请求阶段(调用service方法)、销毁阶段(调用destroy方法)。
二、初始化阶段
<servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.iss.servlet.MyServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet>
(父类的init和destory方法是空实现,此处应该是初始化的同时调用init方法而不是init方法进行初始化,当然重写了init方法以初始化变量也算初始化操作,大致是这意思。)
如果servlet出现修改容器也会重新加载,加载时机为如果添加了load-on-startup则会在卸载后自动加载,如果没加则是用户第一次请求时加载。
三、接收与响应请求阶段
接收和响应都会调用service方法,然后service方法再通过判断请求类型来调用doXX方法,解释再多也没用,放源码
/** * Receives standard HTTP requests from the public * <code>service</code> method and dispatches * them to the <code>do</code><i>XXX</i> methods defined in * this class. This method is an HTTP-specific version of the * {@link javax.servlet.Servlet#service} method. There's no * need to override this method. * * @param req the {@link HttpServletRequest} object that * contains the request the client made of * the servlet * * @param resp the {@link HttpServletResponse} object that * contains the response the servlet returns * to the client * * @exception IOException if an input or output error occurs * while the servlet is handling the * HTTP request * * @exception ServletException if the HTTP request * cannot be handled * * @see javax.servlet.Servlet#service */ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); if (ifModifiedSince < (lastModified / 1000 * 1000)) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } } else if (method.equals(METHOD_HEAD)) { long lastModified = getLastModified(req); maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if (method.equals(METHOD_POST)) { doPost(req, resp); } else if (method.equals(METHOD_PUT)) { doPut(req, resp); } else if (method.equals(METHOD_DELETE)) { doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) { doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) { doTrace(req,resp); } else { // // Note that this means NO servlet supports whatever // method was requested, anywhere on this server. // String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[1]; errArgs[0] = method; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); } }
四、销毁阶段
在该应用停止或者容器停止时,销毁并调用servlet的destroy方法,然后被gc回收。
当servlet修改后,需要重新加载时也会销毁先前的servlet对象并调用destroy方法。
(此处也应该是销毁的同时调用了destroy方法,而不是调用destroy进行销毁)