Servlet 的生命周期详解
目录
1、Servlet 的生命周期
2、Spring 中一个 Controller 是一个Servlet 吗?
3、在 Spring 中有多少个 Servlet ?
4、DispatcherServlet 的生命周期
5、Servlet 生命周期和 ServletRequest 生命周期的区别
1、Servlet 的生命周期
Servlet 生命周期指的是 Servlet 对象从创建到销毁的整个过程,包括以下阶段:
加载和实例化阶段(loading and instantiation):当 Servlet 容器启动或者第一次请求某个 Servlet 时,会加载并创建 Servlet 对象的实例。在此阶段,容器会调用 ServletContext 的 getServlet 方法来获取 Servlet 实例,并调用其 init 方法进行初始化。在 init 方法中,Servlet 可以进行一些初始化工作,如加载配置文件、建立数据库连接等。
就绪阶段(ready):当 Servlet 初始化完成后,容器会将其放入就绪状态,表示它已经准备好处理客户端请求了。
请求处理阶段(request handling):当客户端发起请求时,Servlet 容器会为每个请求创建一个新的线程,并调用 Servlet 的 service 方法处理请求。在 service 方法中,Servlet 可以读取请求数据、进行业务处理,并生成响应数据发送给客户端。
销毁阶段(destruction):当 Servlet 容器关闭或者 Web 应用程序被卸载时,会调用 Servlet 的 destroy 方法,此时 Servlet 会执行一些清理工作,如关闭数据库连接、保存会话数据等。在销毁阶段结束后,Servlet 实例将被销毁并释放资源。
需要注意的是,Servlet 生命周期中 init 和 destroy 方法只会在 Servlet 实例创建和销毁时被调用一次,而 service 方法则会在每个请求到达时被调用一次。此外,Servlet 还可以实现其他生命周期方法,如 init(ServletConfig config)、getServletConfig() 等,以提供更加灵活的初始化和配置方式。
一般情况下,Servlet只有在容器关闭时才会被销毁,但也可以通过Servlet的destroy()方法手动销毁Servlet。当Servlet不再被需要时,可以通过调用destroy()方法来释放资源、关闭数据库连接、取消注册等操作。Servlet的生命周期是整个应用程序中Servlet的初始化、请求处理和销毁的过程。
Servlet 生命周期流程如下图所示:
下面通过一个案例加深对 Servlet 生命周期的理解:
@WebServlet("/myServletLife")
public class MyServletLife extends HttpServlet {private static final long serialVersionUID = 1L;private int initCount = 0;private int httpCount = 0;private int destoryCount = 0;@Overridepublic void destroy() {destoryCount++;super.destroy();// 向控制台输出destory方法被调用次数System.out.println("**********************************destroy方法:" + destoryCount + "*******************************");}@Overridepublic void init() throws ServletException {initCount++;super.init();// 向控制台输出init方法被调用次数System.out.println("调用init方法:" + initCount);}public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {httpCount++;// 控制台输出doGet方法次数System.out.println("doGet方法:" + httpCount);// 设置返回页面格式与字符集resp.setContentType("text/html;charset=UTF-8");PrintWriter writer = resp.getWriter();// 向页面输出writer.write("初始化次数:" + initCount + "<br/>" + "处理请求次数:" + httpCount + "<br/>" + "销毁次数:" + destoryCount);writer.close();}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {this.doGet(request, response);}
}
启动 Tomcat,在地址栏输入“localhost:8080/web/myServletLife”,多次访问 MyServlet,结果如下图。
关闭 Tomcat 服务器,控制台输出如下图
2、Spring 中一个 Controller 是一个Servlet 吗?
在 Spring 中,每个 Controller 类并不是一个 Servlet,而是通过 Servlet 映射器(HandlerMapping)和适配器(HandlerAdapter)来将 HTTP 请求映射到相应的方法进行处理。
具体来说,Spring MVC 框架使用了 DispatcherServlet 作为前置控制器,负责接收客户端的请求并将请求分发给相应的 Controller 进行处理。DispatcherServlet 会根据配置的 Servlet 映射器和适配器来选择合适的 Controller 类,并将请求转发给该类中的具体方法进行处理。在方法中,可以通过注解来定义请求参数、返回值和异常处理等信息,从而更加方便地实现业务逻辑的编写。
因此,虽然每个 Controller 类并不是一个 Servlet,但在 Spring MVC 框架中,它们可以像 Servlet 一样接收并处理 HTTP 请求。同时,Spring 还提供了很多方便的注解和工具类来简化 Controller 类的编写,使得开发者可以更加专注于业务逻辑的实现。
// Controller 只是 springmvc 中的处理器,通过 Servlet 映射器去匹配
3、在 Spring 中有多少个 Servlet ?
在一个 Spring 应用程序中,通常会有一个或多个 Servlet。其中,最常见的是 DispatcherServlet,它是 Spring MVC 框架的核心组件之一,负责接收客户端请求并将请求分发给相应的 Controller 进行处理。
除了 DispatcherServlet,Spring 还提供了一些其他的 Servlet,包括:
ContextLoaderServlet:用于在 Web 应用程序启动时加载 Spring 配置文件,并将 ApplicationContext 对象存储在 ServletContext 中供其他组件使用。
FrameworkServlet:是 DispatcherServlet 的父类,用于处理与 Spring 框架相关的 Servlet 请求,如请求映射、视图解析等。
HttpPutFormContentFilter:用于处理 PUT 请求中的表单数据。
OpenEntityManagerInViewFilter:用于在 Web 请求结束时自动关闭 EntityManager,以避免因为长时间持有 EntityManager 导致的内存泄漏。
DelegatingFilterProxy:是一个通用的过滤器代理,可以将过滤器的实现委托给 Spring 容器中的任意一个 Bean 实例。
需要注意的是,除了 DispatcherServlet 外,其他的 Servlet 大多是一些辅助性的组件,用于解决一些特定的问题,如处理 PUT 请求中的表单数据、自动关闭 EntityManager 等。开发者在使用 Spring 框架时,一般只需要关注 DispatcherServlet 的配置和使用即可。
4、DispatcherServlet 的生命周期
DispatcherServlet 是 Spring MVC 框架中的一个核心组件,它作为前置控制器负责接收客户端请求并将请求分发给相应的 Controller 进行处理。它的生命周期可以分为以下几个阶段:
初始化阶段(Initialization):在容器启动时,Servlet 容器会自动创建 DispatcherServlet 实例并调用其 init() 方法进行初始化。在初始化阶段中,DispatcherServlet 会读取并解析配置文件(如 web.xml 或注解配置等),创建必要的组件对象(如 HandlerMapping、HandlerAdapter 等),并将它们存储在 ServletContext 中,以便于在后续的请求处理中使用。
请求处理阶段(Request Handling):当客户端发送请求时,Servlet 容器会将请求交给 DispatcherServlet 进行处理。在请求处理阶段中,DispatcherServlet 会根据配置的 HandlerMapping 找到匹配的 Controller,然后调用相应的 Controller 方法进行处理。在方法执行过程中,DispatcherServlet 会根据配置的 HandlerAdapter 对请求参数进行解析,将其转换为方法所需的类型,并将方法的执行结果封装为 ModelAndView 对象。最后,DispatcherServlet 会调用 ViewResolver 将 ModelAndView 对象转换为相应的视图,并将视图渲染后的结果返回给客户端。
销毁阶段(Destruction):当 Servlet 容器关闭时,会调用 DispatcherServlet 的 destroy() 方法进行销毁。在销毁阶段中,DispatcherServlet 会释放所有的资源(如 HandlerMapping、HandlerAdapter 等),并清除 ServletContext 中的相应对象。
需要注意的是,由于 DispatcherServlet 是一个单例对象,因此它的生命周期与整个应用程序的生命周期是一致的,即在应用程序启动时创建,在应用程序关闭时销毁。在处理请求时,DispatcherServlet 会创建一个新的线程来处理每个请求,因此它的请求处理阶段是并发的,可以处理多个请求同时到达的情况。
DispatcherServlet 异步处理请求的源码展示:
在 DispatcherServlet 中创建新的线程来处理请求的代码位于 doService() 方法中。以下是部分源码示例:
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {// 获取处理器HandlerExecutionChain mappedHandler = getHandler(request);// 获取处理器适配器HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// 使用 Callable 封装请求和响应final ModelAndView exMv = ha.handle(request, response, mappedHandler.getHandler());// 创建新线程处理请求if (asyncManager.isConcurrentHandlingStarted()) {return;}// 判断是否支持异步处理if (exMv != null && exMv.isAsyncStarted()) {if (isAsyncDispatch(request)) {// 使用 Spring 的异步机制进行处理if (request.getAsyncContext().getTimeout() > 0) {asyncManager.setTaskTimeout(request.getAsyncContext().getTimeout());}asyncManager.startCallableProcessing(new DispatcherServletCallable(exMv), request, response, mappedHandler.getHandler());return;}}// 同步处理请求ha.handle(request, response, mappedHandler.getHandler());
}
可以看到,在 doService() 方法中,当判断可以使用异步处理时,DispatcherServlet 会使用 Spring 的异步机制进行处理,其中 asyncManager.startCallableProcessing() 方法会创建一个新的线程来处理请求。这样就实现了异步处理请求,提高了系统的吞吐量和响应速度。
5、Servlet 生命周期和 ServletRequest 生命周期的区别
Servlet的生命周期是整个应用程序中Servlet的初始化、请求处理和销毁的过程,而ServletRequest的生命周期是单次请求中HttpServletRequest和HttpServletResponse对象的创建和销毁的过程。
具体来说,当Servlet容器接收到一个请求时,容器会为该请求创建一个新的HttpServletRequest对象和HttpServletResponse对象,这两个对象只在当前请求中有效,处理完请求后会被销毁,如果是同一个客户端发起的新请求,Servlet容器会再次创建HttpServletRequest和HttpServletResponse对象。// req和rep只在当前请求中有效,处理完请求后会被销毁,可以理解为方法的出栈
在ServletRequest的生命周期中,HttpServletRequest和HttpServletResponse对象会被传递给Servlet的service()方法,Servlet可以通过这两个对象获取请求参数、设置响应头、发送响应数据等操作。当请求处理完毕后,Servlet容器会自动销毁HttpServletRequest和HttpServletResponse对象,释放资源。
所以,Servlet的生命周期是应用程序级别的,而ServletRequest的生命周期是请求级别的。
Servlet 的生命周期详解相关推荐
- Fragment生命周期详解
关于Fragment的生命周期,博主写过Activity与Fragment生命周期详解,基本上把Fragment的生命周期详细介绍过,但是那仅仅是创建一个Fragmnet时的生命周期,而事实上Frag ...
- Android面试之Activity生命周期详解
Activity生命周期详解 一 Activity的四种状态: Activity的生命周期中存在四种基本的状态:活动状态(Active/Runing),暂停状态(Paused),停止状态(Stoppe ...
- Fragment的懒加载与生命周期详解
提示:本文仅为笔者学习记录 Fragment的懒加载与生命周期详解 什么是懒加载 了解Fragment的生命周期 onAttach onCreate onCreateView onActivityCr ...
- vue 声明周期函数_Vue 生命周期详解
Vue 生命周期详解 Vue 生命周期流程 最开始,用户使用 new Vue() 创建根 Vue 实例,或者 Vue 实例化子组件都会调用_init方法(我们将这两种实例都称为vm): functio ...
- 01.软件项目管理与敏捷方法——敏捷项目生命周期详解笔记
01.软件项目管理与敏捷方法--敏捷项目生命周期详解笔记 00.与其说是船还不如说是熟练的航行技术保证了成功的航行.--George William Curtis 01.敏捷项目是一个按照敏捷宣言宗旨 ...
- taro生命周期详解
taro生命周期详解 taro介绍 生命周期 react的钩子函数 为兼容小程序的钩子函数 个别生命周期详解以及注意 1.render()函数 2.constructor()构造函数 3.在各个生命周 ...
- Eclipse中Maven常用命令以及Maven生命周期详解
Eclipse中maven常用的命令 在某一个maven项目右键快捷方式,然后点击Run As就可以发现几个Maven的命令: Maven Build: 这个命令用于编译Maven工程,执行命令后会在 ...
- Spring 生命周期详解
Spring 生命周期详解 一.传统JAVA bean的生命周期 使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了. 一旦bean不再被使用,则由Java自动进行垃圾回 ...
- flutter 生命周期详解
flutter 生命周期详解 简介 一.widget 生命周期 二.APP 生命周期 总结 简介 众所周知,程序是有生命周期的,那么flutter 的生命周期是什么呢? flutter 的生命周期大体 ...
最新文章
- Internet Explorer 已停止工作 解决办法
- (二)GitHub的使用随记
- SVN创建不了资源库位置 解决方案
- 连载08:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)...
- checkbox全选和反选功能
- css3之背景属性之background-size
- java 代码重排_Java中指令重排
- 【洛谷p1164】小A点菜
- 快速计算网络地址和广播地址
- mysql 根据经纬度查询范围点
- 实现微信公众号评论回复功能
- burpSuit抓取app的数据包
- HUAWEIWATCH GT3有哪些功能?华为新款手表测评
- Pytorch 利用Facenet和Retinaface实现人脸识别
- 网易云课堂---布尔教育《8小时学会html》 笔记
- Developing 2D Games with Unity 免积分下载
- 动画程序时长缩放是什么意思_Pr预设:2000种文字标题排版指示线图形动画无缝转场剪辑工具包...
- 《Unity Magica Cloth从入门到详解》之(8)视野外剔除系统
- 那些年,关于 Java 的那些事儿
- 颜色的搭配 色彩标准卡 各行各业设计人员必看