JavaWeb应用程序的生命周期由Servlet容器控制,Servlet是JavaWeb应用的核心组件,所以知道Servlet生命周期也就知道了JavaWeb应用程序的生命周期。
Servlet生命周期分为三个阶段:初始化阶段、运行时阶段、销毁阶段,这三个阶段分别对用Servlet接口中的三个方法
javax.servlet.Servlet.init(ServletConfig) javax.servlet.Servlet.service(ServletRequest, ServletResponse) javax.servlet.Servlet.destroy()
init()方法:服务器调用该方法初始化Servlet
service()方法:初始化完毕,服务器调用该方法响应客户的请求
destroy()方法:服务器调用该方法消灭servlet对象
其中,init()方法只在Servlet第一次被请求加载的时候被调用一次,当有客户再请求Servlet服务时,Web服务器将启动一个新的线程,在该线程中,调用service方法响应客户的请求
通过程序来验证Servlet生命周期中所对应的接口,创建一个Servlet别实现这三个方法
public class LifecycleServlet extends HttpServlet { public LifecycleServlet() { System.out.println("constructor LifecycleServlet"); } @Override public void init() throws ServletException { System.out.println("init()"); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("service()"); } @Override public void destroy() { System.out.println("destroy()"); } }
访问这个Servlet,并且多次访问,然后关闭Tomcat,我在eclipse下,关闭时是stop the server,不是不是console里面的terminate,控制台输出如下,可以看到多次访问时只调用了service方法
信息: Server startup in 1346 ms constructor LifecycleServlet init() service() service() service() 信息: Stopping service Catalina destroy()
Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
查看HttpServlet源码,ServletRequest被转HttpServletRequest,然后在重载的service中根据请求确实做了分发的操作,源码我删掉了一些与请求分发无关的代码
public abstract class HttpServlet extends GenericServlet { @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)) { doGet(req, resp); } 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 { 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接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。HttpServlet指能够处理HTTP请求的servlet(添加与HTTP协议相关API),它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
Servlet接口中的定义的init()签名为
public void init(ServletConfig config) throws ServletException;
LifecycServlet中覆写的init()为
public void init() throws ServletException {}
自己覆写的和接口定义的不一样,是因为在GenericServlet中被覆写了,看一下源码就知道了,所以继承HttpServlet的类只要覆写init()就可以,因为有参数的init()会调用LifecycServlet中无参数的init()
public abstract class GenericServlet implements Servlet, ServletConfig,java.io.Serializable { @Override public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { // NOOP by default } }
Servlet也可以配置随容器一起启动,在web.xml中配置<load-on-startup>,取值为0-9,数字越小优先级越高
<servlet> <servlet-name>LifecycleServlet</servlet-name> <servlet-class>lifecycle.LifecycleServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
console输出,但tomcat启动之LifecycServlet也启动了
十一月 07, 2015 10:30:55 上午 org.apache.catalina.core.StandardEngine startInternal 信息: Starting Servlet Engine: Apache Tomcat/7.0.41 十一月 07, 2015 10:30:56 上午 org.apache.catalina.util.SessionIdGenerator createSecureRandom 信息: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [176] milliseconds. constructor LifecycleServlet init() 十一月 07, 2015 10:30:56 上午 org.apache.catalina.startup.HostConfig deployDirectory
Servlet接口中的init()签名是有参数传入的,一个ServletConfig对象,这个对象可以获得web.xml中配置的初始化参数
javax.servlet.Servlet.init(ServletConfig)
相关推荐
servlet生命周期演示,便于理解servlet工作流程。
servlet生命周期详解
SERVLET生命周期与JSP生命周期比较
Servlet生命周期与工作原理Servlet使用
达内学习笔记,servlet生命周期,十分详细,保证一看就懂
servlet生命周期详细图解,矢量图。 详细的解释请参考本人博客:http://blog.csdn.net/dwyers/article/details/38435949
servlet生命周期和模版设计模式,包括代码以及相关文档
关于对Servlet声明周期的图例示意!
山寨qq项目1.登录界面教你学会制作qq登录及后台运行。
Servlet 生命周期
Java WEB 篇七 Servlet 生命周期
注:本示例中有5章图片,但因为上传比较麻烦,所以就放在附件中 博文链接:https://lvp.iteye.com/blog/234610
Servlet技术 两条主线 1、HTTP协议 2、Servlet生命周期
从三个阶段来描述servlet的生命周期:初始化阶段、运行阶段和销毁阶段。