(转)Servlet的生命周期——初始化、运行、销毁全部过程
背景:面试中很基础的一个问题,所以有必要好好整理一番。
Servlet体系结构是建立在 Java 多线程机制上的,它的生命周期由 Web 容器负责。
当客户端第一次请求某个 Servlet 时,Servlet 容器将会根据 web.xml 的配置文件实例化这个 Servlet 类。当有新的客户端请求该 Servlet 时,一般不会再实例化该 Servlet 类。
当有多个请求时,Servlet 容器会起多个线程来访问同一个 Servlet 实例的 service() 方法,如果该 Servlet 实例中有共享的实例变量,需要注意多线程安全问题。
生命周期
Servlet 生命周期定义了 Servlet 从创建到毁灭的整个过程,总共分为四个步骤。
调用 init() 方法初始化
调用 service() 方法来处理客户端的请求
调用 destroy() 方法释放资源,标记自身为可回收
被垃圾回收器回收
init() 方法
init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,用于 Servlet的初始化,初始化的数据,可以在整个生命周期中使用。
在下列时刻Servlet容器装载Servlet,共三种情况:
1,Servlet容器启动时自动装载某些Servlet,实现它只需要在web.XML文件中的<Servlet></Servlet>之间添加如下代码:
<loadon-startup>1</loadon-startup>
说明:
在servlet的配置当中,<load-on-startup>5</load-on-startup>的含义是:
标记容器是否在启动的时候就加载这个servlet。
当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;
当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。
正数的值越小,启动该servlet的优先级越高。
2,在Servlet容器启动后,客户首次向Servlet发送请求
3,Servlet类文件被更新后,重新装载Servlet
Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。
初始化阶段步骤:
Ø Servlet容器加载servlet类,把它的. Class文件中的数据读到内存中。
Ø Servlet容器创建servletConfig对象。servletConfig对象包含了servlet的初始化配置信息。此外servlet容器还会使得servletConfig对象与当前的web应用的servletContext对象关联。
Ø Servlet容器创建servlet对象。
Ø Servlet容器调用servlet对象的init(ServletConfig config)方法。
通过初始化步骤,创建了servlet对象和servletConfig对象,并且servlet对象与servletConfig对象关联,而servletConfig对象又与当前对象的servletContext对象关联。当servlet容器完成servlet后,servlet对象只要通过getServletContext()方法就能得到web应用的servletContext对象。
service() 方法
service() 方法是执行实际任务的主要方法。 Servlet 容器(Tomcat、Jetty等)调用 service() 方法来处理来自客户端(浏览器)的请求,并把相应结果返回给客户端。
每次 Servlet 容器接收到一个 Http 请求, Servlet 容器会产生一个新的线程并调用 Servlet实例的 service 方法。 service 方法会检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut、doDelete 方法。所以,在编码请求处理逻辑的时候,我们只需要关注 doGet()、或doPost()的具体实现即可。
对于Tomcat来说,它会将传递过来的参数放在一个Hashtable中,该Hashtable的定义是:
private Hashtable<String String[]> paramHashStringArray = new Hashtable<String String[]>();
这是一个String-->String[]的键值映射。
HashMap线程不安全的,Hashtable线程安全。
destroy() 方法
destroy() 方法也只会被调用一次,在 Servlet 生命周期结束时调用。destroy() 方法主要用来清扫“战场”,执行如关闭数据库连接、释放资源等行为。
调用 destroy 方法之后,servlet 对象被标记为垃圾回收,等待 JVM 的垃圾回收器进行处理。

引申
Servlet何时被创建:
1,默认情况下,当WEB客户第一次请求访问某个Servlet的时候,WEB容器将创建这个Servlet的实例。
2,当web.xml文件中如果<servlet>元素中指定了<load-on-startup>子元素时,Servlet容器在启动web服务器时,将按照顺序创建并初始化Servlet对象。
注意:在web.xml文件中,某些Servlet只 有<serlvet>元素,没有<servlet-mapping>元素,这样我们无法通过url的方式访问这些 Servlet,这种Servlet通常会在<servlet>元素中配置一个<load-on-startup>子元素,让容 器在启动的时候自动加载这些Servlet并调用init()方法,完成一些全局性的初始化工作。
Web应用何时被启动:
1,当Servlet容器启动的时候,所有的Web应用都会被启动
2,控制器启动web应用
Servlet与JSP的比较:
有许多相似之处,都可以生成动态网页。
JSP的优点是擅长于网页制作,生成动态页面比较直观,缺点是不容易跟踪与排错。
Servlet是纯Java语言,擅长于处理流程和业务逻辑,缺点是生成动态网页不直观。
Servlet工作原理:
首先简单解释一下Servlet接收和响应客户请求的过程,首先客户发送一个请求,Servlet是调用service()方法对请求进行响应 的,通过源代码可见,service()方法中对请求的方式进行了匹配,选择调用doGet,doPost等这些方法,然后再进入对应的方法中调用逻辑层 的方法,实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet,doPost等等这些方法 的,HttpServlet中定义了这些方法,但是都是返回error信息,所以,我们每次定义一个Servlet的时候,都必须实现doGet或 doPost等这些方法。
每一个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到 Servlet的生命周期,分别是上文提到的init(),service(),destroy()方法。GenericServlet是一个通用的,不 特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet,因此 HttpServlet也实现了Servlet接口。所以我们定义Servlet的时候只需要继承HttpServlet即可。
Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以 HttpServlet中实现了service()方法,并将请求ServletRequest,ServletResponse强转为 HttpRequest和HttpResponse。
public void service(ServletRequest req,ServletResponse res)
throws ServletException,IOException
{
HttpRequest request;
HttpResponse response; try
{
req = (HttpRequest)request;
res = (HttpResponse)response;
}catch(ClassCastException e)
{
throw new ServletException("non-HTTP request response");
}
service(request,response);
}
代码的最后调用了HTTPServlet自己的service(request,response)方法,然后根据请求去调用对应的doXXX方法,因为HttpServlet中的doXXX方法都是返回错误信息,
protected void doGet(HttpServletRequest res,HttpServletResponse resp)
throws ServletException,IOException
{
String protocol = req.getProtocol();
String msg = IStrings.getString("http.method_get_not_supported");
if(protocol.equals("1.1"))
{
resp.sendError(HttpServletResponse.SC.METHOD.NOT.ALLOWED,msg);
}
esle
{
resp.sendError(HttpServletResponse.SC_BAD_REQUEST,msg);
}
}
(转)Servlet的生命周期——初始化、运行、销毁全部过程的更多相关文章
- servlet的生命周期与运行时的线程模型
第 14 章 生命周期 注意 讲一下servlet的生命周期与运行时的线程模型,对了解servlet的运行原理有所帮助,这样才能避免一些有冲突的设计. 如果你不满足以下任一条件,请继续阅读,否则请跳过 ...
- Servlet的生命周期与运行原理
Servlet的生命周期: 1 加载classLoader 2 实例化 new 3 初始化 init(ServletConfig) 4 处理请求 service doGet d ...
- JSP Servlet WEB生命周期
[转载] JavaWeb的生命周期是由Servlet容器来控制的总的来说分为三个阶段1.启动阶段:加载web应用相关数据,创建ServletContext对象,对Filter和servlet进行初始化 ...
- JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...
- servlet的生命周期与工作原理、使用!
概念: Servlet是一个java程序运行在服务器上,处理客户端请求并做粗响应的程序!Servlet是和平台无关的服务器组件,它运行在Servlet容器中,Servlet容器 负责servlet和客 ...
- Servlet的生命周期?
Servlet何时被创建: 1,默认情况下,当WEB客户第一次请求访问某个Servlet的时候,WEB容器将创建这个Servlet的实例. 2,当web.xml文件中如果<servlet> ...
- (转)JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...
- 说一说Servlet的生命周期
servlet有良好的生存期的定义,包括加载和实例化.初始化.处理请求以及服务结束.这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达. Se ...
- Java Web -- Servlet(5) 开发Servlet的三种方法、配置Servlet具体解释、Servlet的生命周期(2)
三.Servlet的生命周期 一个Java servlet具有一个生命周期,这个生命周期定义了一个Servlet怎样被加载并被初始化,怎样接收请求并作出对请求的响应,怎样被从服务中清除.Servlet ...
随机推荐
- windows平台下编辑的内容传到linux平台出现中文乱码的解决办法
现象说明:在windows下编辑的内容,上传到linux平台下出现中文乱码.如下: 在windows平台编写haha.txt文件,内容如下: 上传到linux平台,出现中文乱码,如下: 基本上面出现的 ...
- curator 分布式锁InterProcessMutex
写这篇文章的目的主要是为了记录下自己在zookeeper 锁上踩过的坑,以及踩坑之后自己的一点认识; 从zk分布式锁原理说起,原理很简单,大家也应该都知道,简单的说就是zookeeper实现分布式锁是 ...
- 第三个Sprint ------第十一天
四则运算APP推广: 1通过微信公众平台推广APP,写一片软文,然后推送出去.分享朋友圈.QQ空间. 2通过微博推广APP,@各微博大户. 3让之前内侧的同学转发给自己的小弟小妹或者侄女侄子! 总结: ...
- 第三次Sprint-最后冲刺
由于一些原因,导致我和汝婷被退队了.因此我们是从上星期重新开始做系统. 陈汝婷单独负责: 1.用户输入题目数: 2.限制题数: 3.自动生成用户需要题目数的题目: 4.计时 练丽云单独: 1.异常处理 ...
- 【Deep Hash】NINH
[CVPR 2015] Simultaneous Feature Learning and Hash Coding with Deep Neural Networks [paper] Hanjiang ...
- c++中常见概念、关键字等的区别
(1).重载,覆盖和隐藏的区别: 重载主要是函数的重载,函数名相同,返回类型相同,但是函数形参不同,被调用时,根据函数形参决定调用原函数还是重载函数. 覆盖主要用在继承多态中,函数前加virtual关 ...
- 使用phpstudy创建本地虚拟主机
在使用php开发网站的时候,每次测试自己的网站时,通常都是用localhost/dirname/filename.php来访问自己所写的程序 但是有时候我们需要模拟真实的场景,如通过域名访问时,如果你 ...
- MYSQL两个数据库字符集保持一致问题
参考这篇文章:https://lzw.me/a/mysql-charset.html 还有一篇官方文档:https://dev.mysql.com/doc/refman/5.7/en/charset. ...
- redux的源码解析
一. redux出现的动机 1. Javascript 需要管理比任何时候都要多的state2. state 在什么时候,由于什么原因,如何变化已然不受控制.3. 来自前端开发领域的新需求4. 我们总 ...
- ASP.NET MVC缓存使用
局部缓存(Partial Page) 1.新建局部缓存控制器: public class PartialCacheController : Controller { // GET: /PartialC ...