Spring mvc之源码 handlerMapping和handlerAdapter分析
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分析的更多相关文章
- Spring MVC之源码速读之RequestMappingHandlerAdapter
spring-webmvc-4.3.19.RELEASE 下面来看DispatcherServlet中的执行: /** * Exposes the DispatcherServlet-specific ...
- Spring IOC 容器源码分析 - 余下的初始化工作
1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...
- Spring IOC 容器源码分析 - 填充属性到 bean 原始对象
1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...
- Spring IOC 容器源码分析 - 循环依赖的解决办法
1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...
- Spring IOC 容器源码分析 - 创建原始 bean 对象
1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...
- Spring IOC 容器源码分析 - 创建单例 bean 的过程
1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...
- Spring IOC 容器源码分析 - 获取单例 bean
1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章.在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一 ...
- Spring IOC 容器源码分析系列文章导读
1. 简介 Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本.经过十几年的迭代,现在的 Spring 框架已经非常成熟了.Spring ...
- Spring IOC 容器源码分析
声明!非原创,本文出处 Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 S ...
随机推荐
- Vue入门教程 第三篇 (条件与循环)
v-if语法(条件) 符合条件时显示(渲染)某一元素. <div id="app"> <div v-if="ok"> <h1> ...
- COGS 2510. 拯救紫萱学姐
[题目描述] 其实在开考前半个小时题面并不是这样的. 由于明天要考试,同学们要把抽屉里的书都搬空,书很多而且办了走读不能回寝室的学长一眼就看到了回班撩他的学姐,于是就把学姐当学长用♂了:“帮我把这摞书 ...
- 对象模型(Object-Model):关于vptr、vtbl
当一个类本身定义了虚函数,或其父类有虚函数时,为了支持多态机制,编译器将为该类添加一个虚函数指针(vptr).虚函数指针一般都放在对象内存布局的第一个位置上,这是为了保证在多层继承或多重继承的情况下能 ...
- VMware15.5版本下安装Windows_Server_2008_R2
一.新建虚拟机 第一步:打开VMware15.5虚拟机,在欢迎界面点击新建虚拟机: 第二步:选择典型(推荐)选项-->适用于新手,单击下一步: 第三步:选定最后一项稍后安装操作系统,单击下一步: ...
- [BZOJ5280] [Usaco2018 Open]Milking Order
Description Farmer John的N头奶牛(1≤N≤105),仍然编号为1…N,正好闲得发慌.因此,她们发展了一个与Farmer John每 天早上为她们挤牛奶的时候的排队顺序相关的复杂 ...
- Cocos2d-x 学习笔记(12) Speed Follow
Speed Follow都是直接继承了Action. Speed对其他action进行包装,改变action的速度. Follow可用于node在scene中的运动,scene将node作为Follo ...
- SpringBootSecurity学习(26)前后端分离版之github单点登录
单点登录(SSO) 关于oauth2.0,最后我们再来学习一下单点登录.前面介绍过单点登录的定义,单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一. ...
- 分布式FastDFS集群部署
FastDFS FastDFS的作者余庆在其 GitHub 上是这样描述的:"FastDFS is an open source high performance distributed f ...
- netty中Pipeline的ChannelHandler执行顺序案例详解
一.netty的Pipeline模型 netty的Pipeline模型用的是责任链设计模式,当boss线程监控到绑定端口上有accept事件,此时会为该socket连接实例化Pipeline,并将In ...
- 前端路由hash、history原理及简单的实践下
阅读目录 一:什么是路由?前端有哪些路由?他们有哪些特性? 二:如何实现简单的hash路由? 三:如何实现简单的history路由? 四:hash和history路由一起实现 回到顶部 一:什么是路由 ...