serlvet生命周期学习笔记

serlvet生命周期应该是java web方向面试必考的问题吧!

一、从API文档来看

public interface Servlet

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的一些方法。这些方法被称为是生命周期方法并且按照以下顺序被调用:

  1. The servlet is constructed, then initialized with the init method.
    1. 1)servlet被构造的时候,调用init方法进行初始化。
  2. Any calls from clients to the service method are handled.
    1. 2)使用service方法处理从客户端的任何请求。
  3. The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.
    1. 3)servlet被去除服务时,调用destroy方法销毁,然后gc收集销毁。

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容器启动时加载,此种servlet可以通过在项目的web.xml文件中添加load-on-startup来标明,中间的数字标明一个启动顺序

 <servlet>
  <servlet-name>MyServlet</servlet-name>
  <servlet-class>com.iss.servlet.MyServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
 </servlet>

其他的servlet在用户第一次请求时加载、实例化初始化并调用init方法。

(父类的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);
        }
    }

此处我们可以看到为什么我们平时重写一个doGet或者doPost等就行了,当然如果重写service方法也是行的,读者可以自行尝试同时重写service方法和doXX。

四、销毁阶段

在该应用停止或者容器停止时,销毁并调用servlet的destroy方法,然后被gc回收。

当servlet修改后,需要重新加载时也会销毁先前的servlet对象并调用destroy方法。

(此处也应该是销毁的同时调用了destroy方法,而不是调用destroy进行销毁)


你可能感兴趣的:(exception,servlet,Servlets,service,interface,methods)