servlet生命周期详解

Servlet程序时运行在服务器端的java程序,生命周期收到web容器的控制。

生命周期有5部分:加载,初始化,服务,销毁,卸载

其生命周期都可以在HttpServlet和GenericServlet中找到对应的方法。

1、加载Servlet

Web容器负责加载Servlet,当web容器启东时或者在第一次使用这个Servlet的时候,容器会负责创建Servlet实例,但是用户必须通过web.xml指定Servlet的位置,成功加载后,Web容器会通过反射的方式对Servlet进行实例化。

2、初始化

当一个servlet被实例化之后,容器将调用init()方法初始化这个对象,以便在处理请求之前完成一些动作。

@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
// NOOP by default
}
在GenericServlet 中init方法有两个重载版本,第一个版本可以接受web.xml中配置的初始化参数。都是钩子方法。

3、服务

          @Override
public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException {
    HttpServletRequest  request;
    HttpServletResponse response;
    try {
        request = (HttpServletRequest) req;
        response = (HttpServletResponse) res;
    } catch (ClassCastException e) {
        throw new ServletException("non-HTTP request or response");
    }
    service(request, response);
}
 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;
            try {
                ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
            } catch (IllegalArgumentException iae) {
                // Invalid date header - proceed as if none was set
                ifModifiedSince = -1;
            }
            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的service方法进行处理,然后service通过反射获取请求方法,转发到相应的doGet()或者其他方法。当自己实现service方法时,如果想直接在service方法里实现逻辑,就不用调用父类的方法。否则,还会先转发到相应的get/post方法里执行后在调用service方法里自己的逻辑。

4、销毁

大部分web容器关闭或者检测到一个servlet要从容器中被删除时,会自动调用destory方法。

@Override
public void destroy() {
// NOOP by default
}
5、卸载

但一个servlet调用玩destory后,此实例将被垃圾回收,当需要再次使用时,将会重新调用init方法。需要注意的是,在正常情况下,Servlet只会初始化一次,但是当Servlet长时间不使用的话,也会被容器自动销毁,而如果需要再次使用时,会重新进行初始化操作,即在特殊情况下初始化操作和销毁操作也会执行多次。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_35368651/article/details/82951900

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值