Servlet 2.4 规范之第三篇:Servlet生命周期
SRV.2.3 Servlet生命周期
servlet有着定义良好且明确的生命周期,它定义了servlet以怎样的方式加载和实例化、初始化、怎样处理客户端请求、以及怎样停止服务。生命周期表现在API中就是javax.servlet.Servlet接口的init、service和destroy三个方法。所有servlet必须直接或者通过GenericServlet/HttpServlet间接实现这些方法。
SRV.2.3.1 加载和实例化
servlet容器负责加载和实例化servlet。加载和实例化可以发生在容器启动时,或者发生在容器判断出servlet需要处理请求时。
servlet引擎启动时,一些基础的必需型servlet必须被定位、找到,然后servlet容器通过正常的Java类加载机制来加载这些servlet。加载可能源于本地文件系统,也可能是远程文件系统,或者是网络服务。
servlet类加载完成后,容器对其进行实例化以备使用。
SRV.2.3.2 初始化
servlet对象实例化之后,容器必须初始化servlet才能用于处理客户端请求。初始化的过程主要用于servlet读取持久化的配置信息,初始化比较耗时的资源如jdbc等,以及执行其他的一次性操作。容器通过调用Servlet接口的init方法来完成servlet实例的初始化,当然,调用init方法时需要传入一个全局唯一配置参数,该参数必须实现了ServletConfig接口。这个配置对象允许servlet从Web 应用程序的配置信息中访问一些名-值对形式的初始化参数。这个配置对象也允许servlet访问servlet运行时环境的一个实现了ServletContext接口的特定对象。关于ServletConfig接口的更多信息请看第三章SRV.3中“Servlet Context”一节。
SRV.2.3.2.1 初始化出错的情况
初始化期间,servlet实例可能会抛出UnavailableException或ServletException。此时,该servlet就不允许提供服务并且servlet容易必须释放它。这时destroy方法是不会被调用的,因为这个servlet根本就没有初始化成功。
初始化失败后,容器可以尝试再次实例化并初始化一个新的实例。当然,如果UnavailableException指明了unavailability的最小不可用时间后,容器必须等过了这段时间后才能创建和初始化新的servlet实例。
SRV.2.3.2.2 关于工具的思考
当一个工具类加载和自检web应用系统时,它的静态初始化方法是完全不同于servlet的init方法的。直到Servlet接口的init方法被调用后,开发人员才应该把当前servlet列为已激活的容器运行时环境。例如,当静态初始化方法被调用时,servlet并不应该尝试建立与数据库或EJB容器的连接,而应该等到Servlet接口的init方法被成功执行后才行。
SRV.2.3.3 请求的处理
servlet正常初始化完成后,容器就可以用它来处理客户端请求了。客户端的请求用ServletRequest类型的实例对象来表示。servlet通过调用ServletResponse类型实例对象的对应方法来生成响应信息,并把响应信息作为Servlet接口中service方法的参数传递下去。
在http请求中,容器提供出来的代表客户端请求和响应信息的对象分别是HttpServletRequest和HttpServletResponse。
值得注意的是,被容器放在服务队列中的Servlet实例可能在它的整个生命周期中都不处理客户端请求。这个是很有可能的,例如整个声明周期中都没有请求过来,那它就不会被执行的。
SRV.2.3.3.1 多线程的问题
servlet容器可能发送多个并发请求给servlet的service方法。为了处理这些请求,serlvet开发人员必须仔细设计service方法,让它可以同时妥善处理这些请求。
开发人员可以通过实现SingleThreadModel接口来强制要求servlet容器去保证每次只有一个请求传给service方法,当然了,这种方式并不建议使用。servlet容器可以通过添加请求排队机制或者维护一个servlet实例池来满足对并发请求的处理要求。如果当前servlet是分布式应用系统的一部分,容器可能会针对分布式环境下的每一个JVM维护一个serlvet实例池,以处理并发请求。
对于没有实现SingleThreadModel接口的servlet,如果service已被定义为同步方法,那对应的servlet容器就不能再使用实例池机制,而只能添加请求排队机制了。强烈建议开发人员不要为service方法实现同步锁,因为这个同步锁会造成很大的性能影响。
SRV.2.3.3.2 请求处理期间的异常
在处理请求期间,servlet是很可能抛出ServletException或UnavailableException的。ServletException标志着处理请求期间发生了一些错误,此时servlet容器应该采取合适的措施清理掉这些请求。
UnavailableException标志着当前servlet临时或永久性的不能处理请求了。
如果UnavailableException明确指示出servlet永久性的出现故障,那么容器必须从服务列表中通过调用servlet的destroy方法去移除并释放servlet实例。然后凡是被容器拒绝的请求都必须返回给客户端一个404响应信息。
如果只是临时性的出现故障,容器可以不再把客户端请求传递给当前servlet,直到该servlet服务恢复正常为止。此时凡是被容器拒绝的请求都必须返回给客户端一个服务不可用(503)响应信息。
当然了,servlet容器完全可以不区分永久性和临时性故障,一视同仁的把所有UnavailableExceptions当作永久性故障,并随后从服务列表中移除出现故障的servlet。
SRV.2.3.3.3 线程安全性
请求和响应对象的实现方式并不是确保线程安全的。这意味着这些对象应该仅被用在请求处理线程的局部范围内。
请求和响应对象的引用绝不应该传递给当前正在执行的其他线程,以免对其他线程的执行结果造成干扰和不确定性。
如果应用创建的线程使用了由容器管理的对象,例如请求或响应对象,这些对象必须确保仅在servlet的服务周期内访问并且这样的线程在servlet的service方法内必须自己独立的生命周期,不然的话访问service方法执行结束后的这些对象很可能产生莫名其妙的各种问题。一定要做到请求和响应对象的线程安全性。如果这些对象不可避免的要在多线程下访问,那必须确保访问的方法已被同步或者对的封装添加线程安全控制,例如,同步一下访问这些请求属性的方法调用,或者在一个线程内使用本地局部变量去响应客户端请求。
SRV.2.3.4 服务结束
某些时间内容器并不需要一直保持着servlet处于服务列表内。一个servlet实例的服务时间并不是固定的,可能只保持一小段时间,或者一直到容器的生命周期终结,或者居于两者之间。
当容器判定一个servlet应该被移除时,它会调用Servlet接口的destroy方法告知servlet释放它使用的任何资源并保存数据。例如,容器很可能在清理内存资源时销毁不必要的servlet,或者是在容器停止服务时。
在servlet容器调用destroy方法前,它必须确保所有正在执行的线程顺利完成所有操作,或者直接等到他们超过时间限制为止。总之,只有所有servlet都执行完了或者已经超过时间限制了,servlet容器才能调用destroy方法销毁servlet。
一旦servlet实例的destroy方法被调用了,容器就不会再传递任何请求给当前servlet实例。如果容器又要启用这个servlet,它也只能等到新的servlet实例启动完成后才传递请求过来。
destroy方法执行完成后,servlet容器必须释放servlet实例,然后垃圾回收机制才会适时回收servlet占用的资源和空间。
文档信息
- 译者:张大爷
- 原文网址:http://www.cnblogs.com/flance/
- 版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
Servlet 2.4 规范之第三篇:Servlet生命周期的更多相关文章
- 转:OSGi 入门篇:生命周期层
OSGi 入门篇:生命周期层 前言 生命周期层在OSGi框架中属于模块层上面的一层,它的运作是建立在模块层的功能之上的.生命周期层一个主要的功能就是让你能够从外部管理应用或者建立能够自我管理的应用(或 ...
- iOS开发UI篇—UITabBarController生命周期(使用storyoard搭建)
iOS开发UI篇—UITabBarController生命周期(使用storyoard搭建) 一.UITabBarController在storyoard中得搭建 1.新建一个项目,把storyb ...
- J2EE的13个规范之(三) Servlet简单介绍
Servlet是一种server端脚本,它是一个特殊的Java类,继承自HttpServlet.开发中主要用于处理和响应client的请求. Servlet在容器中执行,事实上例的和销毁创建由容器进行 ...
- Servlet 2.4 规范之第七篇:过滤器
过滤器是一套java组件,用于在请求—>资源—>应答的这一过程中即时转换处理负载和头信息. 本章讲述了Servlet 2.4 API中一些类和方法,这些类和方法提供了一套轻量级框架用于过滤 ...
- Servlet 2.4 规范之第六篇:响应
响应对象封装了服务端返回给客户端的所有信息.在HTTP协议中,这些信息通过HTTP头和消息体传送. SRV.5.1 缓冲 出于效率考量,servlet容器可以缓冲输出数据,但这并非强制要求.常见 ...
- Servlet 2.4 规范之第五篇:请求
request对象封装了来自客户端的所有请求信息.在HTTP协议中,客户端发给服务端的所有信息都是通过request对象的请求头和请求体来传送的. SRV.4.1 HTTP协 ...
- Servlet 2.4 规范之第四篇:Servlet上下文
SRV.3.1 ServletContext接口说明 ServletContext接口定义了运行servlet的web应用中和servlet相关的视图信息.容器提供者负责提供ServletCon ...
- Servlet(三):生命周期、常用方法、常见错误
Servlet的生命周期:从第一次调用,到服务器关闭.如果在web.xml 中配置了load-on-startup则是从服务器开启到服务器关闭. 注意: * init方法是对Servlet进行初始化的 ...
- servlet篇 之 生命周期
二:Servlet的生命周期 背景知识: servlet是单例,在web项目运行期间,一个servlet只会创建一个对象[tomcat帮我们实例 化][尽量不要在servlet中定义成员变量].因为w ...
随机推荐
- (71)Received empty response from Zabbix Agent问题解决
刚接触zabbix新手少部分会出现如下错误: Received empty response from Zabbix Agent at [192.168.1.2]. Assuming that age ...
- Linux菜鸟起飞之路【七】文件合并、归档和压缩
一.文件合并操作 1.覆盖符号与追加符号 a)“>”代表将左边文件的内容覆盖右边文件的内容,如果右边文件不存在则创建这个文件 b)“>>”代表将左边文件的内容追加到右边文件中,如果右 ...
- python 程序小测试
python 程序小测试 对之前写的程序做简单的小测试 ... # -*- encoding:utf-8 -*- ''' 对所写程序做简单的测试 @author: bpf ''' def GameOv ...
- MySQL迁移升级解决方案
任务背景 由于现有业务架构已不能满足当前业务需求,在保证数据完整的前提下,现需要将原有数据库迁移到另外一台单独的服务器上,在保证原有服务正常的情况下,将原有LAMP环境中mysql数据库版本5.6.3 ...
- sqlmanagementstudio2008下载地址
http://big.wy119.com/sqlmanagementstudio2008_x86_chs.zip
- ACM 贪心算法总结
贪心算法的本质: 就是当前状态的最优解,它并不考虑全局. 什么是当前状态的最优解? 成本问题? https://www.cnblogs.com/xuxiaojin/p/9400892.html (po ...
- NOIP 2017 小凯的疑惑
# NOIP 2017 小凯的疑惑 思路 a,b 互质 求最大不能表示出来的数k 则k与 a,b 互质 这里有一个结论:(网上有证明)不过我是打表找的规律 若 x,y(设x<y) 互质 则 : ...
- 两种图片延迟加载的方法总结jquery.scrollLoading.js与jquery.lazyload.js
估计网上能查到的最多的两种图片延迟加载方法就是jquery.scrollLoading.js与jquery.lazyload.js了,其中jquery.lazyload.js的调用方法因为有网友爆出的 ...
- 【水】ZYH记
我从十二岁起,便在sdoj的蒟蒻餐厅里当伙计,root说,样子太傻,怕侍候不了专职切题,就在外面做点事罢.外面的调试管理,虽然容易说话,但唠唠叨叨缠夹不清的也很不少.他们往往要亲眼看着一个字一个字编译 ...
- 零基础学习 Python 之数字与运算
写在之前 大家好,这里是零基础学习 Python 系列,在这里我将从最基本的 Python 写起,然后再慢慢涉及到高阶以及具体应用方面.我是完全自学的 Python,所以很是明白自学对于一个人的考验, ...