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. parse_args(argsparse):python和命令行之间的交互

    初始化 假设我们创建一个“argp.py”的文件. import argparse # 引入模块 # 建立解析对象 parser = argparse.ArgumentParser() parser. ...

  2. COGS 2510. 拯救紫萱学姐

    [题目描述] 其实在开考前半个小时题面并不是这样的. 由于明天要考试,同学们要把抽屉里的书都搬空,书很多而且办了走读不能回寝室的学长一眼就看到了回班撩他的学姐,于是就把学姐当学长用♂了:“帮我把这摞书 ...

  3. 局部敏感哈希LSH(Locality-Sensitive Hashing)——海量数据相似性查找技术

    一. 前言     最近在工作中需要对海量数据进行相似性查找,即对微博全量用户进行关注相似度计算,计算得到每个用户关注相似度最高的TOP-N个用户,首先想到的是利用简单的协同过滤,先定义相似性度量(c ...

  4. Bran的内核开发教程(bkerndev)-06 全局描述符表(GDT)

    全局描述符表(GDT)   在386平台各种保护措施中最重要的就是全局描述符表(GDT).GDT为内存的某些部分定义了基本的访问权限.我们可以使用GDT中的一个索引来生成段冲突异常, 让内核终止执行异 ...

  5. 从零开始搭建前端监控系统(三)——实现控制iframe前进后退

    前言 本系列文章旨在讲解如何从零开始搭建前端监控系统. 项目已经开源 项目地址: https://github.com/bombayjs/bombayjs (web sdk) https://gith ...

  6. [Luogu3069][USACO13JAN]牛的阵容Cow Lineup

    题目描述 Farmer John's N cows (1 <= N <= 100,000) are lined up in a row. Each cow is identified by ...

  7. wait,notify,notifyAll详细介绍

    https://www.cnblogs.com/pangyang/articles/5916349.html

  8. linux+jenkins+github+python持续集成

    1.服务器上事先安装jenkins   参见:linux上war包方式安装Jenkins 2.新建一个自由风格的job,名字随意起 3.配置git(拉取github代码) 从github复制pytho ...

  9. JavaScript ES6函数式编程(三):函子

    前面二篇学习了函数式编程的基本概念和常见用法.今天,我们来学习函数式编程的最后一个概念--函子(Functor). 相信有一部分同学对这个概念很陌生,毕竟现在已经有很多成熟的轮子,基本能满足我们日常的 ...

  10. 初级开发者也能码出专业炫酷的3D地图吗?

    好看的3D地图搭建出来,一定是要能为开发者所用与业务系统开发中才能真正地体现价值.基因于此,CityBuilder建立了与ThingJS的通道——直转ThingJS代码,支持将配置完成的3D地图一键转 ...