【Spring MVC】DispatcherServlet 请求处理流程

一、 请求处理

Spring MVC 是 Spring 框架的一部分,用于构建 Web 应用程序。它遵循 MVC(Model-View-Controller)设计模式,将应用程序分为模型(Model)、**视图(View)控制器(Controller)**三个部分。

DispatcherServlet 处理流程:

在这里插入图片描述

  1. 当用户发起请求时,会将请求直接传入前端控制器 DispatcherServlet ,它是 Spring MVC 核心组件,负责接收请求并分发到各自的处理器中
  2. DispatcherServlet 接收到请求后,会调用 HandlerMapping 组件。HandlerMapping 根据请求的 URL 查找合适的处理器(Handler)。这里的 Handler 通常是指 Controller 中的方法,这些方法通常带有 @RequestMapping 注解(或其变体如 @GetMapping , @PostMapping 等)。
  3. DispatcherServlet 获取到合适的 Handler 后,会调用 HandlerAdapter 组件。HandlerAdapter 负责执行处理器方法,并处理方法的返回值。HandlerAdapter同样会去 Handler (Controller)中找那些带有 @RequestMapping 注解的方法
  4. HandlerAdapter 调用 Controller 中的方法,执行业务逻辑。处理完业务后,会返回一个 ModelAndView 对象给 HandlerAdapter。ModelAndView 对象中包含模型数据(Model)和视图名称(View)。
  5. DispatcherServlet 从 HandlerAdapter 获取到 ModelAndView 对象后,会调用 ViewResolver 组件。ViewResolver 负责将视图名称解析为实际的视图对象。
  6. DispatcherServlet 获取到具体的视图对象后,将模型数据传递给视图对象View进行渲染。
  7. 渲染完成后,DispatcherServlet 将生成的响应内容返回给用户,浏览器显示最终的页面。

在这里插入图片描述

  1. 客户端发出请求,会先经过 filter 过滤,通过的请求才能到达 DispatcherServlet。
  2. DispatcherServlet 通过 handlerMapping 找到请求对应的 handler,返回一个 HandlerExecutionChain 里面包含 interceptors 和 handler
  3. DispatcherServlet 通过 handlerAdapter 调用实际的 handler 处理业务逻辑, 返回 ModelAndView。里面会包含逻辑视图名和 model 数据。注意,在此之前和之后,会分别调用 interceptors 拦截处理
  4. 调用 viewResolver 将逻辑视图名解析成 view 返回
  5. 调用 view.render 渲染视图,写进 response。然后 interceptors 和 filter 依次拦截处理,最后返回给客户端

HandlerInterceptor

拦截器。在 handler 执行前后及视图渲染后执行拦截,可以注册不同的 interceptor 定制工作流程

public interface HandlerInterceptor {// 在 handler 执行前拦截,返回 true 才能继续调用下一个 interceptor 或者 handlerdefault boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}// 在 handler 执行后,视图渲染前进行拦截处理default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable ModelAndView modelAndView) throws Exception {}// 视图渲染后,请求完成后进行处理,可以用来清理资源// 除非 preHandle 放回 false,否则一定会执行,即使发生错误default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable Exception ex) throws Exception {}}

二、设计原理

Servlet 规范

SpringMVC 是基于 Servlet 的。

Servlet 是运行在 web 服务器上的程序,它接收并响应来自 web 客户端的请求(通常是 HTTP 请求)。

Servlet 规范有三个主要的技术点: Servlet, Filter, Listener

1. Servlet

Servlet 是实现 Servlet 接口的程序。对于 HTTP, 通常继承 javax.servlet.http.HttpServlet, 可以为不同的 URL 配置不同的 Servlet。Servlet 是"单例"的,所有请求共用一个 Servlet, 因此对于共享变量(比如实例变量),需要自己保证其线程安全性。DispatcherServlet 便是一个 Servlet。

Servlet 生命周期

  1. Servlet 实例化后,Servlet 容器会调用 init 方法初始化。init 只会被调用一次,且必须成功执行才能提供服务。
  2. 客户端每次发出请求,Servlet 容器调用 service 方法处理请求。
  3. Servlet 被销毁前,Servlet 容器调用 destroy 方法。通常用来清理资源,比如内存,文件,线程等。
2. Filter

Filter 是过滤器,用于在客户端的请求访问后端资源之前,拦截这些请求;或者在服务器的响应发送回客户端之前,处理这些响应。只有通过 Filter 的请求才能被 Servlet 处理。

Filter 可以通过配置(xml 或 java-based)拦截特定的请求,在 Servlet 执行前后(由 chain.doFilter 划分)处理特定的逻辑,如权限过滤,字符编码,日志打印,Session 处理,图片转换等

Filter 生命周期

  1. Filter 实例化后,Servlet 容器会调用 init 方法初始化。init 方法只会被调用一次,且成功执行(不抛出错误且没有超时)才能提供过滤功能

  2. 客户端每次发出请求,Servlet 容器调用 doFilter 方法拦截请求。

    public void  doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {// 客户端的请求访问后端资源之前的处理逻辑System.out.println("我在 Servlet 前执行");// 把请求传回过滤链,即传给下一个 Filter, 或者交给 Servlet 处理chain.doFilter(request,response);// 服务器的响应发送回客户端之前的处理逻辑System.out.println("我在 Servlet 后执行");
    }
    
  3. Filter 生命周期结束时调用 destroy 方法,通常用来清理它所持有的资源,比如内存,文件,线程等。

3. Listener

Listener 是监听某个对象的状态变化的组件,是一种观察者模式。

被监听的对象可以是域对象 ServletContext, Session, Request

监听的内容可以是域对象的创建与销毁,域对象属性的变化

ServletContextHttpSessionServletRequest
对象的创建与销毁ServletContextListenerHttpSessionListenerServletRequestListener
对象的属性的变化ServletContextAttributeListenerHttpSessionAttributeListenerServletRequestAttributeListener

WebApplicationContext

SpringMVC 用 Spring 化的方式来管理 web 请求中的各种对象。

什么是 Spring 化? IOC 和 AOP, 这不是本文的重点,具体自行查阅。

SpringMVC 会通过 WebApplicationContext 来管理服务器请求中涉及到的各种对象和他们之间的依赖关系。

WebApplicationContext 继承自 ApplicationContext, 它定义了一些新的作用域,提供了 getServletContext 接口。

public interface WebApplicationContext extends ApplicationContext {// 根容器名,作为 key 存储在 ServletContext 中; ServletContext 持有的 WebApplicationContextString ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";/*** 这三个是 WebApplicationContext 特有的作用域* 通过 WebApplicationContextUtils.registerWebApplicationScopes 注册相应的处理器*/String SCOPE_REQUEST = "request";String SCOPE_SESSION = "session";String SCOPE_APPLICATION = "application";/*** ServletContext 在 WebApplicationContext 中的名字* 通过 WebApplicationContextUtils.registerEnvironmentBeans 注册到 WebApplicationContext 中*/String SERVLET_CONTEXT_BEAN_NAME = "servletContext";/*** ServletContext 和 ServletConfig 配置参数在 WebApplicationContext 中的名字* ServletConfig 的参数具有更高的优先级,会覆盖掉 ServletContext 中的参数* 值为 Map<String, String> 结构*/String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";/*** ServletContext 属性信息在 WebApplicationContext 中的名字* 值为 Map<String, String> 结构* 属性是用来描述 ServletContext 本身的一些信息的*/String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";/*** 获取 ServletContext 接口*/@NullableServletContext getServletContext();}
WebApplicationContext 类图

img

ApplicationContext 有一个抽象实现类 AbstractApplicationContext, 模板方法的设计模式。它有一个 refresh 方法,它定义了加载或初始化 bean 配置的基本流程。后面的实现类提供了不同的读取配置的方式,可以是 xml, annotation, web 等,并且可以通过模板方法定制自己的需求。

AbstractApplicationContext 有两个实现体系, 他们的区别是每次 refresh 时是否会创建一个新的 DefaultListableBeanFactory。DefaultListableBeanFactory 是实际存放 bean 的容器, 提供 bean 注册功能。

  1. AbstractRefreshableApplicationContext 这个 refreshable 并不是指 refresh 这个方法,而是指 refreshBeanFactory 这个方法。他会在每次 refresh 时创建一个新的 BeanFactory(DefaultListableBeanFactory)用于存放 bean,然后调用 loadBeanDefinitions 将 bean 加载到新创建的 BeanFactory。
  2. GenericApplicationContext 内部持有一个 DefaultListableBeanFactory, 所以可以提前将 Bean 加载到 DefaultListableBeanFactory, 它也有 refreshBeanFactory 方法,但是这个方法啥也不做。

根据读取配置的方式,可以分成 3 类,基于 xml 的配置, 基于 annotation 的配置基于 java-based 的配置

  1. 基于 xml 的配置使用 xml 作为配置方式, 此类的名字都含有 Xml, 比如从文件系统路径读取配置的 FilePathXmlApplicationContext, 从 ClassPath 读取配置的 ClassPathXmlApplicationContext, 基于 Web 的 XmlWebApplicationContext 等
  2. 基于注解的配置通过扫描指定包下面具有某个注解的类,将其注册到 bean 容器,相关注解有 @Component, @Service, @Controller, @Repository,@Named 等
  3. java-based 的配置方式目前是大势所趋,结合注解的方式使用简单方便易懂,主要是 @Configuration 和 @Bean

上面几个类是基础类,下面是 SpringMVC 相关的 WebApplicationContext

  1. XmlWebApplicationContext 和 AnnotationConfigWebApplicationContext 继承自 AbstractRefreshableApplicationContext,表示它们会在 refresh 时新创建一个 DefaultListableBeanFactory, 然后 loadBeanDefinitions。 它们分别从 xml 和 注解类(通常是 @Configuration 注解的配置类)中读取配置信息。

  2. XmlEmbeddedWebApplicationContext 和 AnnotationConfigEmbeddedWebApplicationContext 继承自 GenericApplicationContext,表示他们内部持有一个 DefaultListableBeanFactory, 从名字可以看出它们是用于 “Embedded” 方面的,即 SpringBoot 嵌入容器所使用的 WebApplicationContext

  3. SpringMVC 应用中几乎所有的类都交由 WebApplicationContext 管理,包括业务方面的 @Controller, @Service, @Repository 注解的类, ServletContext, 文件处理 multipartResolver, 视图解析器 ViewResolver, 处理器映射器 HandleMapping 等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/461455.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[ 问题解决篇 ] win11远程桌面报错:出现身份验证错误要求的函数不受支持(附完整解决方案)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

汽车免拆诊断案例 | 2010款起亚赛拉图车发动机转速表指针不动

故障现象  一辆2010款起亚赛拉图车&#xff0c;搭载G4ED 发动机&#xff0c;累计行驶里程约为17.2万km。车主反映&#xff0c;车辆行驶正常&#xff0c;但组合仪表上的发动机转速表指针始终不动。 故障诊断  接车后进行路试&#xff0c;车速表、燃油存量表及发动机冷却温度…

自动化运维

自动化运维是指使用工具和脚本自动化管理、配置、监控和维护IT基础设施的过程。通过自动化运维&#xff0c;可以提高工作效率&#xff0c;减少人为错误&#xff0c;增加系统的可预测性和稳定性。以下是实现自动化运维的常见步骤和工具&#xff1a; 常见步骤&#xff1a; 1. 定义…

驱动——线程断链和信息获取

实验环境&#xff1a;win7 x32 断链&#xff1a; #include <ntifs.h>NTSTATUS EnumThread(ULONG ulPid, ULONG ulTid) {PEPROCESS pProcessAddr PsGetCurrentProcess();PLIST_ENTRY pHeadlink (PLIST_ENTRY)((ULONG)pProcessAddr 0xb8);PLIST_ENTRY pNextlink pHead…

AWD挨打记录

前言 昨天参加了星盟的AWD集训&#xff0c;本来寻思能猛猛乱杀&#xff0c;结果加固时间只有20分钟&#xff0c;WAF还没push上去就被三家上了不死马QAQ cms是站帮主&#xff0c;之前没打过&#xff0c;D盾啥也没扫出来&#xff0c;还寻思是个贼安全的系统&#xff0c;结果洞满…

鸿蒙打包hvigorw clean报错No npmrc file is matched in the current user folder解决

问题 在执行hvigorw clean等命令时&#xff0c;报错如下&#xff1a; Error: The hvigor depends on the npmrc file. No npmrc file is matched in the current user folder. Configure the npmrc file first解决方案 在用户当前目录下新建.npmrc文件&#xff0c;并配置如下…

前端如何实现进度条

将进度条的宽度动态控制&#xff0c;通过css的transition动画来控制 <template><div class"container"><div class"base-progress"><div class"inner" :style"{ width: w % }"><div class"text&qu…

SWAT-MODFLOW地表水与地下水耦合实践技术

耦合模型被应用到很多科学和工程领域来改善模型的性能、效率和结果&#xff0c;SWAT作为一个地表水模型可以较好的模拟主要的水文过程&#xff0c;包括地表径流、降水、蒸发、风速、温度、渗流、侧向径流等&#xff0c;但是对于地下水部分的模拟相对粗糙&#xff0c;考虑到SWAT…

江协科技STM32学习- P27 实验-串口发送/串口接收

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

Linux笔记--基础入门

文章目录 Linux基础知识点文件目录*磁盘分区**基础命令*Linux运行级别关机重启手册alias别名ntsysv系统服务管理程序 Linux常用命令命令分类命令行格式选项参数 命令行辅助操作 真常用命令()help命令&#xff1a;帮助指令man手册页manual page绝对路径与相对路径绝对路径&#…

11月1日星期五今日早报简报微语报早读

11月1日星期五&#xff0c;农历十月初一&#xff0c;早报#微语早读。 1、六大行今日起实施存量房贷利率新机制。 2、谷歌被俄罗斯罚款35位数&#xff0c;罚款远超全球GDP。 3、山西吕梁&#xff1a;女性35岁前登记结婚&#xff0c;给予1500元奖励。 4、我国人均每日上网时间…

Pandas DataFrame学习补充

1. 从字典创建&#xff1a;字典的键成为列名&#xff0c;值成为列数据。 import pandas as pd# 通过字典创建 DataFrame df pd.DataFrame({Column1: [1, 2, 3], Column2: [4, 5, 6]}) 2. 从列表的列表创建&#xff1a;外层列表代表行&#xff0c;内层列表代表列。 df pd.Da…

<项目代码>YOLOv8 煤矸石识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

推荐一款功能强大的文字处理工具:Atlantis Word Processor

Atlantis word proCEssor是一款功能强大的文字处理工具。该软件可以让用户放心的去设计文档&#xff0c;并且软件的界面能够按用户的意愿去自定义&#xff0c;比如工具栏、字体选择、排版、打印栏等等&#xff0c;当然还有更多的功能&#xff0c;比如你还可以吧软件界面中的任何…

「虚拟现实中的心理咨询:探索心灵世界的新方法」

内容概要 当我们想到虚拟现实时&#xff0c;很多人会联想到游戏或娱乐&#xff0c;但如今其在心理咨询领域的应用正在逐渐崭露头角。传统的心理咨询方式常常局限在咨询室内&#xff0c;面临着空间和情感隔阂的问题。然而&#xff0c;沉浸式环境的出现&#xff0c;使得治疗者能…

图像修复与重建——几何失真(畸变)的概念

一 几何失真&#xff08;畸变&#xff09;的概念 在实际的成像系统中&#xff0c;图像捕捉介质平面和物体平面之间不可避免地存在有一定的转角和倾斜角。转角对图像的影响是产生图像旋转&#xff0c;倾斜角的影响表现为图像发生投影变形。另外一种情况是由于摄像机系统本身的原…

Spark的集群环境部署

一、Standalone集群 1.1、架构 架构&#xff1a;普通分布式主从架构 主&#xff1a;Master&#xff1a;管理节点&#xff1a;管理从节点、接客、资源管理和任务 调度&#xff0c;等同于YARN中的ResourceManager 从&#xff1a;Worker&#xff1a;计算节点&#xff1a;负责利…

使用 Python 的 BeautifulSoup 与 Flask/Flask-RESTful 集成进行数据爬取和 API 构建

使用 Python 的 BeautifulSoup 与 Flask/Flask-RESTful 集成进行数据爬取和 API 构建 在现代 Web 开发中&#xff0c;许多应用需要从其他网页提取数据并将其呈现为 API 服务。Python 的 BeautifulSoup 是一个流行的 HTML 解析库&#xff0c;用于从网页抓取和解析数据&#xff…

江协科技STM32学习- P28 USART串口数据包

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

Verilog实现的莫尔斯电码发生器

莫尔斯或者摩尔斯电码(Morse Code)&#xff0c;发明于1837年(另有一说是1836年)&#xff0c;通过不同的排列顺序来表达不同的英文字母、数字和标点符号&#xff0c;在这里作一简单处理&#xff0c;仅产生点(Dit)和划(Dah)&#xff0c;时长在0.25秒之内为点&#xff0c;超过为划…