Spring mvc之源码 handlerMapping和handlerAdapter分析

本篇并不是具体分析Spring mvc,所以好多细节都是一笔带过,主要是带大家梳理一下整个Spring mvc的执行流程,以及如何根据URL查找处理器Controller的实现

(适合那些刚阅读源码不知道如何下手的人)

http://www.guojinbao.com/borrow/borrowDetail/GETadLPjnf0[d].do

如何根据URL地址----》找到正确处理器Controller的相应方法Method

注:概念 IOC容器:负责bean的创建和维护bean与bean关系的一个大的集合

①dispatcherServlet 在Spring MVC为所有请求入口,标准的servlet。

标准的servlet执行流程为

1.init()  首次加载servlet 整个servlet生命周期只执行一次

2.service()  依据url-pattern(<url-pattern>/</url-pattern> 拦截所有请求,不包括静态资源文件) 拦截模式,匹配请求模式,匹配成功调用service方法

3.destroy()  servlet容器(如:tomcat停止)结束调用

执行流程如下

第一步 执行 HttpServletBean-->init()方法

init()方法我们只需要关注initServletBean()方法 此方法为抽象方法由FrameworkServlet实现

有兴趣的可以具体看一下源码,整个init()方法 为spring mvc的IOC容器初始化

注:Spring 的IOC容器初始化由contextLoaderListener完成

Spring IOC容器建议配置:数据库连接,事务,与第三方框架集成等等

如:ApplicationContext.xml  (小提示:处理器Controller的扫描 可以交给springMVC IOC容器完成,目的分层明确,便于IOC容器查找 )  

Spring mvc IOC 容器 配置:

第二部 拦截请求

① FrameworkServlet -->service()

分发请求

② FrameworkServlet--->processRequest(request, response);

③ DispatcherServlet--->doService(HttpServletRequest request, HttpServletResponse response)

如何根据URL找到处理器执行正确的方法就在此方法中

④ DispatcherServlet--->doDispatch(HttpServletRequest request, HttpServletResponse response)

第①部分

这里为啥不是调用super.service(request,response)?

最直接的理由:如果直接调用service方法 根据method类型进行分发请求就直接跳出框架啦(你懂的嘿嘿)

②③2步有兴趣的可以看一下源码

第④部分

DispatcherServlet--->doDispatch(HttpServletRequest request, HttpServletResponse response)

整个过程如下:

>>1. 获取url对应的处理器controller以及相应方法

>>2. 获取执行处理器中方法的对象

>>3. 具体执行

Spring mvc是如何通过URL查找到对应的处理器controller以及对应的方法尼?需要知道以下3个核心接口handlerMapping,handlerAdapter,RequestCondition我们不具体分析相应接口的实现以及具体逻辑,过程相当复杂,1到2句话说

不清楚,这里给大家留一个直观的考量。

由于Spring mvc源码庞大,建议看源码的时候,只看重点部分或者说自己感兴趣部分。我们大家常用是在类和方法加上注解@RequestMapping来标识访问路径,我们以此模板给大家量化分析url查询处理器controller以及相应方法的过程

handlerMapping:负责查找URL对应的处理器Controller

RequestMappingInfo:根据注解@RequestMapping生成方法匹配策略

handlerAdapter:负责绑定参数,执行请求,处理返回值

handlerMapping 接口就一个方法返回HandlerExecutionChain

HandlerExecutionChain

DispatcherServlet--->doDispatch()

第一步 获取HandlerExecutionChain

在DispatcherServlte的servlet初始化中(调用init()方法)中调用onRefresh()完成handlerMappings的初始化

第二步 获取handlerAdapter 找到和handlerMapping匹配的handlerAdapter

初始化过程同第一步

DispatcherServlte会根据handlerMapping与已经注册好了的HandlerAdapter一一匹配,看哪一种HandlerAdapter是支持该handlerMapping类型的,

如果找到了其中一种HandlerAdapter是支持传过来的handlerMapping类型,那么该HandlerAdapter会调用自己的handle方法,handle方法运用Java的反射机制执行controller的具体方法来获得ModelAndView

以handlerMapping的实现RequestMappingHandlerMapping为例

由于实现了InitializingBean,当RequestMappingHandlerMapping完成bean的初始化后,会调用afterPropertiesSet()-->initHandlerMethods();完成以下操作

①生成直接URL-->RequestMappingInfo,映射操作

②生成 RequestMappingInfo--->handlerMethod映射操作

③将所有的RequestMappingInfo注册到容器中

注:

RequestMappingInfo实现了RequestCondition接口 存储着根据注解@RequestMapping生成方法匹配策略

举个例子

PatternsRequestCondition的初始化相当于

PatternsRequestCondition(“/user/applicationShow/{id}”)当请求URL符合此规则是就匹配成功

简单滴说,RequestMappingInfo是将注解@RequestMapping的信息提取出来

生成此方法的匹配条件

阅读RequestMappingHandlerMapping源码流程如下(主要是为了梳理出重点部分)

综上所述我们来猜测一下spring mvc 中根据URL找到处理器Controller中相应方法的流程

①:获取Request的URL

②:从UrlLookup这个map中找到相应的requestMappingInfo

③:如果没找到则遍历所有requestMappingInfo的信息直到找到匹配的requestMappingInfo

④:根据requestMappingInfo到mappingLookup中找到handlerMethod

handlerMethod接口如下:

到这里大家差不多就明白了吧,有了处理器实例,方法,参数调用反射执行方法分分钟的事情

当然spring mvc真正执行比这个复杂的多啦,但是执行的时候是逃不出这个套路的。

具体的URL找到处理器Controller中相应方法的流程请大家看一下DispatcherServlet--》getHandler()方法

注:

最后说一下RequestMappingHandlerMapping并不是默认的查找处理器方法的策略,他是通过  <mvc:annotation-driven />配置完成容器注册的

Spring mvc之源码 handlerMapping和handlerAdapter分析的更多相关文章

  1. Spring MVC之源码速读之RequestMappingHandlerAdapter

    spring-webmvc-4.3.19.RELEASE 下面来看DispatcherServlet中的执行: /** * Exposes the DispatcherServlet-specific ...

  2. Spring IOC 容器源码分析 - 余下的初始化工作

    1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...

  3. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...

  4. Spring IOC 容器源码分析 - 循环依赖的解决办法

    1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...

  5. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  6. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  7. Spring IOC 容器源码分析 - 获取单例 bean

    1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章.在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一 ...

  8. Spring IOC 容器源码分析系列文章导读

    1. 简介 Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本.经过十几年的迭代,现在的 Spring 框架已经非常成熟了.Spring ...

  9. Spring IOC 容器源码分析

    声明!非原创,本文出处 Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 S ...

随机推荐

  1. Python学习笔记五(读取提取写入文件)

    #Python打开读取一个文件内容,然后写入一个新的文件中,并对某些字段进行提取,写入新的字段的脚本,与大家共同学习. import os import re def get_filelist(dir ...

  2. django渲染高阶

    08.16自我总结 django渲染高阶 一.利用母版渲染 1.创建母版文件 如:stamper.html <!DOCTYPE html> <html lang="en&q ...

  3. Head First设计模式——观察者模式

    1.气象监测应用,错误示范 有一个气象站,分别有三个装置:温度感应装置,湿度感应装置,气压感应装置.WeathData对象跟踪气象站数据,WeathData有MeasurmentsChanged()方 ...

  4. pdfminer API介绍:pdf网页爬虫

    安装 pip install pdfminer 爬取数据是数据分析项目的第一个阶段,有的加密成pdf格式的文件,下载后需要解析,使用pdfminer工具. 先介绍一下什么是pdfminer 下面是官方 ...

  5. 网站是HTTP?10分钟变成HTTPS!域名免费添加配置SSL证书,变成https//环境

    对于小程序request请求需要https域名.navigator.geolocation定位也需要在https环境下才可以生效等问题: 前端开发越来越需要https环境来来测试一下API接口和各类问 ...

  6. Halcon一日一练:图像分割之基本概念

    1.什么是图像分割: 图像分割就是把图像中特定的目标提出来,进行处理. 2.为什么要做图像分割: 图像分割是由图像处理到图像分析的关键步骤,准确的来说,没有图像分割,图像处理将无法实现其后续的操作.进 ...

  7. httprunner-1-linux下搭建hrun(上)

    前言 相信不少小伙伴对开源项目 httprunner 都很感兴趣,我们来看下它的有哪些特点吧: 项目管理:新增项目.列表展示及相关操作,支持用例批量上传(标准化的HttpRunner json和yam ...

  8. CodeForces - 1214D B2. Books Exchange (hard version)

    题目链接:http://codeforces.com/problemset/problem/1249/B2 思路:用并查集模拟链表,把关系串联起来,如果成环,则满足题意.之后再用并查集合并一个链,一个 ...

  9. NOIP2018提高组初赛游记

    AH省的,好像水军多,走的都比较早(莫非是真·大佬!!) 本人考了71,较去年退步了.(去年还考80多的来着) 题目坑.. 第一.二大题选择 第三题年份,看了试卷标题,第二十二届,算出来后没有这个选项 ...

  10. 像使用SQL一样对List对象集合进行排序

    在开始之前,我先卖个关子提一个问题:假设我们有一个Movie类,这个类有三个成员变量分别是starred(是否收藏), title(电影名称), rating(评分).你知道怎么对一个Movie对象组 ...