SpringMVC组件原理剖析

这篇具有很好参考价值的文章主要介绍了SpringMVC组件原理剖析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringMVC组件原理剖析

主要剖析DispatcherServlet(前端控制器 )初始化的过程,还有DispatcherServlet执行主流程

一、 前端控制器初始化

DispatcherServlet初始化做了两件事情

  • 获得了一个 SpringMVC 的 ApplicationContext容器
  • 注册了 SpringMVC的 九大组件

SpringMVC组件原理剖析

1.1 初始化SpringMVC容器

前端控制器DispatcherServlet是SpringMVC的入口,也是SpringMVC的大脑,主流程的工作都是在此完成的

DispatcherServlet 本质是个Servlet,当配置了 load-on-startup 时,会在服务器启动时就执行创建和执行初始化init方法,每次请求都会执行service方法

找一下init方法,发现DispatcherServlet类中没有,就去找他爹FrameworkServlet类,爹也没有,就一直找,直到HttpServletBean类中有一个init方法

找到init方法,看到调用了一个initServletBean方法,点进去看看

SpringMVC组件原理剖析

initServletBean方法如下所示,发现啥也没有,说明是子类实现的,也就是FrameworkServlet类

SpringMVC组件原理剖析

在FrameworkServlet类中找到initServletBean方法,然后发现有下面一条语句,获取web环境下的Spring容器

SpringMVC组件原理剖析

点进去看看,发现创建了一个Spring的容器

SpringMVC组件原理剖析

还是此方法,再往下看,把Spring容器的引用作为参数放入了下面的方法中

传入Spring容器有什么作用?

​ 将Spring容器的引用设置为SpringMVC的一个属性,通过这个地方体现出一个父子容器的关系

SpringMVC组件原理剖析

父子容器有什么作用?

当SpringMVC在获取Bean的时候,首先会从自己的容器中获取,如果自己容器没有的话会使用parent找到父容器,也就是Spring容器,再从里面看看有没有对应的Bean

Spring中能不能获取到SpringMVC中的Bean?

不能,因为SpringMVC是子容器

SpringMVC组件原理剖析

1.2 注册了 SpringMVC的 九大组件

没太屡明白141-SpringMVC框架-组件原理剖析-前端控制器初始化-注册九大组件_哔哩哔哩_bilibili

当我们把SpringMVC容器创建出来后,会执行到下面标红的语句

configureAndRefreshWebApplicationContext,配置和刷新SpringMVC容器

SpringMVC组件原理剖析

继续往下走,如果没有的话就进行创建

SpringMVC组件原理剖析

点进上图中的方法,一直点到下图

发现也有configureAndRefreshWebApplicationContext方法的调用

SpringMVC组件原理剖析

经过上面两个过程,不管是新创建的SpringMVC容器还是只有就有的SpringMVC容器,都会执行configureAndRefreshWebApplicationContext方法




点进方法configureAndRefreshWebApplicationContext

发现此方法中有一个refresh方法

SpringMVC组件原理剖析

点进refresh方法,发现最后调用了一个finishRefresh方法,完成刷新

SpringMVC组件原理剖析

点进去finishRefresh方法看一下,此方法中发布了一个事件

我们设置上这个事件,事件对应的监听都会执行

SpringMVC组件原理剖析




此时再回到FrameworkServlet类

找到下面这个方法,是一个监听器,监听的东西就是泛型ContextRefreshedEvent,也就是我们发布的事件的类型(上图)

这段FrameworkServlet.this.onApplicationEvent(event);代码会执行

为什么会被执行?

在另一个地方会发布事件

SpringMVC组件原理剖析

​ 其中在FrameworkServlet类中有一个监听器就是监听上面的事件的

​ 监听到后这段FrameworkServlet.this.onApplicationEvent(event);代码会执行

SpringMVC组件原理剖析

看一下onApplicationEvent方法,里面有一个onRefresh方法,

SpringMVC组件原理剖析

看一下onRefresh方法,但是内部什么也没写,说明是子类进行实现

SpringMVC组件原理剖析

看一下FrameworkServlet类的子类DispatcherServlet类中的onRefresh方法

SpringMVC组件原理剖析

最后完成注册SpringMVC九大组件

SpringMVC组件原理剖析

1.3 处理器映射器初始化细节

注册了九个组件,我们可以选一个我们比较熟悉的initHandlerMappings进行查看

这一步的操作就是看看Spring容器之中有没有类型是HandlerMapping的组件,如果有的话,matchingBeans参数就不是空了

SpringMVC组件原理剖析

那此时就进不去下面这个if判断了,就不会加载默认配置文件中的组件

SpringMVC组件原理剖析

打断点之后发现,为什么会有四个HandlerMapping类型的参数?

SpringMVC组件原理剖析

我们之前配置了一个注解@EnableWebMVC

SpringMVC组件原理剖析

或者说spring-mvc.xml文件中的

SpringMVC组件原理剖析

MVC注解驱动的作用有很多,会帮我们向SpringMVC中注入一些组件,其中HandlerMapping就是在这个地方注册的

上面这几句话的操作都是@EnableWebMVC注解帮我们完成的

如果我们把@EnableWebMVC注解注释掉调后,matchingBeans参数的大小就是0,最终会加载默认配置文件中的组件,就是下图框起来的

SpringMVC组件原理剖析

四个HandlerMapping类型的组件,我们点开看一个

但是我们只手动配置了一个拦截器,为什么会显示两个呢?

Spring本身提供了两个

SpringMVC组件原理剖析

再看一下MappingRegistery参数

SpringMVC组件原理剖析

随便点进去一个看看

SpringMVC组件原理剖析

二、前端控制器执行主流程

当服务器启动时,DispatcherServlet 会执行初始化操作,接下来,每次访问都会执行service方法,我们先宏观的看一下执行流程,在去研究源码和组件执行细节

SpringMVC组件原理剖析

2.1 定位doDispatcher方法

在DispatcherServlet类中找service方法,但是没有,那就找他爹FrameworkServlet类,发现有Service方法,但是此方法不是最原生的,最原生的方法是ServletRequest参数

SpringMVC组件原理剖析

再找FrameworkServlet类的爹HttpServletBean类,但是没有Service方法

再找HttpServlet类,发现有Service方法,并且是原生的(参数前面没有http)

SpringMVC组件原理剖析

上图中的service方法又调用了下面的service方法(这个service进行重载了)

内部根据请求方式,看看是调用dopost还是doGet

SpringMVC组件原理剖析

我们可以看一下doPost方法,但是此方法左边有一个小标志,说明已经被子类覆盖了

SpringMVC组件原理剖析

点一下小标志,然后进入到FrameworkServlet类中,并看到doPost方法

SpringMVC组件原理剖析

doPost方法中又调用了一个processRequest方法

SpringMVC组件原理剖析

processRequest方法中又调用了doService方法,但是我们发现doService是一个抽象方法,我们需要找到对应的实现

SpringMVC组件原理剖析

看一下doService抽象方法的具体实现,就到了DispatcherServlet类

doService方法中调用了另外一个方法doDispatch

SpringMVC组件原理剖析

看一下doDispatch方法,最核心的主流程就在这里

2.2 验证HandlerExecutionChain

从DispatcherServlet类中的doDispatch开始找

此方法中有一个参数HandlerExecutionChain,这个参数内部包括Interceptor、目标对象

此方法中 this.getHandler(processedRequest)的调用对HandlerExecutionChain的参数mappedHandler进行初始化

SpringMVC组件原理剖析

我们看一下getHandler方法是什么,如下所示

如果参数handlerMappings不是空,就对其进行循环

SpringMVC组件原理剖析

那handlerMappings参数是什么呢?点进去看看

发现就是最终装HandlerMapping的集合

HandlerMapping的的填充在前面1.3进行讲解了

SpringMVC组件原理剖析

再回到getHandler方法,其中遍历集合的时候又调用了mapping.getHandler(request)方法

SpringMVC组件原理剖析

我们再看一下mapping.getHandler方法是干嘛的

SpringMVC组件原理剖析

找对应的实现,选择第一个

SpringMVC组件原理剖析

然后再这个类中对应的实现又调用了getHandlerExecutionChain方法

SpringMVC组件原理剖析

再看一下getHandlerExecutionChain方法

SpringMVC组件原理剖析

最终这个chain参数就返回到doDispatcher方法,如下标红的位置

SpringMVC组件原理剖析

上面的过程,就是下图中标红的地方

SpringMVC组件原理剖析

2.3 HandlerAdapter执行目标方法

doDispatcher方法还没有完成,继续往下看

再往下走会调用getHandlerAdapter方法

SpringMVC组件原理剖析

继续往下走,会执行拦截器的preHandle前置方法

SpringMVC组件原理剖析

执行目标方法

SpringMVC组件原理剖析

执行后置方法

SpringMVC组件原理剖析

然后我们发现执行前置方法和后置方法的时候并不是HandlerAdapter对象执行的

但是执行目标方法的时候是HandlerAdapter对象执行的

然后我们可以看一下handle方法,执行目标方法

发现没有实现,我们看一下子类的实现

SpringMVC组件原理剖析

选择下图中的第一个

SpringMVC组件原理剖析

顺着截图向下走

SpringMVC组件原理剖析

SpringMVC组件原理剖析

最终到了下面这个地方

SpringMVC组件原理剖析

继续执行,会进入到下面标红的方法中

SpringMVC组件原理剖析

继续点进去

SpringMVC组件原理剖析

SpringMVC组件原理剖析

到了下面这个地方,看一下参数

SpringMVC组件原理剖析

上图的参数就是在我们访问时对应的参数

SpringMVC组件原理剖析

再点进doInvoke方法

SpringMVC组件原理剖析

然后发现了执行method.invoke(this.getBean(), args)方法

反射代码,最终通过反射执行目标方法

SpringMVC组件原理剖析文章来源地址https://www.toymoban.com/news/detail-481451.html

到了这里,关于SpringMVC组件原理剖析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 15、SpringMVC之常用组件及执行流程

    DispatcherServlet 是前端控制器,由框架提供,不需要工程师开发; 作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求。 HandlerMapping 是处理器映射器,由框架提供,不需要工程师开发; 作用:根据请求的 url、method 等信息去查找 Handler(即控制

    2024年02月05日
    浏览(61)
  • Flutter原理篇:GestureDetector原理深度剖析及手势原理(上)

    今天我们来讲讲GestureDetector的深度剖析,只有了解原理了,才能知道手势冲突如何解决以及如何更灵活的运用手势。 我们先来看看GestureDetector的内部结构 1. GestureDetector 只是一个包装类,最终还是由 Listener 的 RenderPointListener 执行事件的操作 2.点击事件开始时会首先执行 RawG

    2024年04月27日
    浏览(38)
  • CVE-2023-28708 原理剖析

    这应该不是一个严重的漏洞,可能评分只能为低,因为并没有什么卵用。 话不多说,直接进入正题 我的复现环境: tomcat-8.5.50 首先我们得简单写一个servlet,当然不写也没事,因为我们的分析到不了处理servlet这一步,只用tomcat默认提供的ROOT就行 首先我们需要在web.xml中注册

    2024年02月09日
    浏览(38)
  • Elasticsearch原理剖析

    Elasticsearch集群方案由EsMaster、EsClient和EsNode1、EsNode2、EsNode3、EsNode4、EsNode5、EsNode6、EsNode7、EsNode8、EsNode9进程组成,如下图所示,模块说明如表下所示。 说明如表: 名称 说明 Client Client使用HTTP或HTTPS协议同Elasticsearch集群中的EsClient以及各EsNode实例进程进行通信,进行分布式索

    2024年02月17日
    浏览(41)
  • ChatGPT原理剖析

    由开发者 准备好的罐头 回应: 下面是一个问答,让ChatGPT讲一个关于人工智慧的笑话,但可以看出来,这个笑话的笑点显然和我们平常人不太一样,显得笑点非常奇怪: 你搜寻之后,ChatGPT从网上搜寻答案, 整理重组 给你想要的答案: 但实际上,多数ChatGPT的答案在网络上都

    2023年04月09日
    浏览(37)
  • ZooKeeper原理剖析

    ZooKeeper是一个分布式、高可用性的协调服务。在大数据产品中主要提供两个功能: 帮助系统避免单点故障,建立可靠的应用程序。 提供分布式协作服务和维护配置信息。 ZooKeeper集群中的节点分为三种角色:Leader、Follower和Observer,其结构和相互关系如下图所示。通常来说,需

    2024年02月16日
    浏览(36)
  • Flink基本原理剖析讲解

    Flink是一个批处理和流处理结合的统一计算框架,其核心是一个提供了数据分发以及并行化计算的流数据处理引擎。它的最大亮点是流处理,是业界最顶级的开源流处理引擎。 Flink最适合的应用场景是低时延的数据处理(Data Processing)场景:高并发pipeline处理数据,时延毫秒级

    2024年02月16日
    浏览(40)
  • ClickHouse原理剖析

    ClickHouse是一款开源的面向联机分析处理的列式数据库,其独立于Hadoop大数据体系,最核心的特点是极致压缩率和极速查询性能。同时,ClickHouse支持SQL查询,且查询性能好,特别是基于大宽表的聚合分析查询性能非常优异,比其他分析型数据库速度快一个数量级。 ClickHouse核心

    2024年02月16日
    浏览(27)
  • JVM原理剖析

    本文讨论的JVM以JDK1.8为基准点,附带会横向比较,往前推到JDK1.6。JVM是任何一个学习JAVA的程序员绕不开的核心,本文就会围绕这个核心展开对它剖析,希望能给广大的程序员带来帮助。 Java Virtual Machine(Java虚拟机)的缩写 JVM是一个标准,一套规范,规定了.class文件在其内部

    2024年02月05日
    浏览(18)
  • Flume原理剖析

    Flume是一个高可用、高可靠,分布式的海量日志采集、聚合和传输的系统。Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。其中Flume-NG是Flume的一个分支,其目的是要明显简单,体积更

    2024年02月13日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包