Spring mvc之源码 handlerMapping和handlerAdapter分析

盛年不重来,一日难再晨,及时当勉励,岁月不待人。这篇文章主要讲述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停止)结束调用

Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

执行流程如下
第一步  执行 HttpServletBean--> init()方法
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

init()方法我们只需要关注initServletBean()方法 此方法为抽象方法由FrameworkServlet实现
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

有兴趣的可以具体看一下源码,整个init()方法 为spring mvc的IOC容器初始化
注:Spring 的IOC容器初始化由contextLoaderListener完成
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

Spring IOC容器建议配置:数据库连接,事务,与第三方框架集成等等
如:ApplicationContext.xml   (小提示:处理器Controller的扫描 可以交给springMVC IOC容器完成,目的分层明确,便于IOC容器查找 )
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
Spring mvc IOC 容器 配置:
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
 
 
第二部 拦截请求
① FrameworkServlet --> service()
分发请求
② FrameworkServlet---> processRequest(request, response);
③ DispatcherServlet---> doService(HttpServletRequest request, HttpServletResponse response)
如何根据URL找到处理器执行正确的方法就在此方法中
④ DispatcherServlet---> doDispatch(HttpServletRequest request, HttpServletResponse response)
  第①部分
 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

这里为啥不是调用super.service(request,response)?
 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

最直接的理由:如果直接调用service方法 根据method类型进行分发请求就直接跳出框架啦(你懂的嘿嘿)
②③2步有兴趣的可以看一下源码
第④部分
DispatcherServlet---> doDispatch(HttpServletRequest request, HttpServletResponse response)
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

整个过程如下:
> > 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
 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

HandlerExecutionChain
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

  DispatcherServlet---> doDispatch()
第一步 获取HandlerExecutionChain
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

在DispatcherServlte的servlet初始化中(调用init()方法)中调用onRefresh()完成handlerMappings的初始化
 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

第二步 获取handlerAdapter 找到和handlerMapping匹配的handlerAdapter
 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

初始化过程同第一步
DispatcherServlte会根据handlerMapping与已经注册好了的HandlerAdapter一一匹配,看哪一种HandlerAdapter是支持该handlerMapping类型的,
如果找到了其中一种HandlerAdapter是支持传过来的handlerMapping类型,那么该HandlerAdapter会调用自己的handle方法,handle方法运用java的反射机制执行controller的具体方法来获得ModelAndView
 
以handlerMapping的实现RequestMappingHandlerMapping为例
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

由于实现了InitializingBean,当RequestMappingHandlerMapping完成bean的初始化后,会调用afterPropertiesSet()--> initHandlerMethods(); 完成以下操作
①生成直接URL--> RequestMappingInfo,映射操作
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
②生成 RequestMappingInfo---> handlerMethod映射操作
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
③将所有的RequestMappingInfo注册到容器中
 
注:
 
RequestMappingInfo实现了RequestCondition接口  存储着根据注解@RequestMapping生成方法匹配策略
 
举个例子
 
 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
PatternsRequestCondition的初始化相当于
PatternsRequestCondition(“/user/applicationShow/{id}”)当请求URL符合此规则是就匹配成功
简单滴说,RequestMappingInfo是将注解@RequestMapping的信息提取出来
生成此方法的匹配条件
 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
阅读RequestMappingHandlerMapping源码流程如下(主要是为了梳理出重点部分)
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
 
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
【Spring mvc之源码 handlerMapping和handlerAdapter分析】 
综上所述我们来猜测一下spring mvc 中根据URL找到处理器Controller中相应方法的流程
①:获取Request的URL
②:从UrlLookup这个map中找到相应的requestMappingInfo
③:如果没找到则遍历所有requestMappingInfo的信息直到找到匹配的requestMappingInfo
④:根据requestMappingInfo到mappingLookup中找到handlerMethod
handlerMethod接口如下:
Spring mvc之源码 handlerMapping和handlerAdapter分析

文章图片

 
到这里大家差不多就明白了吧,有了处理器实例,方法,参数调用反射执行方法分分钟的事情
当然spring mvc真正执行比这个复杂的多啦,但是执行的时候是逃不出这个套路的。
具体的URL找到处理器Controller中相应方法的流程请大家看一下DispatcherServlet--》getHandler()方法
注:
 
最后说一下RequestMappingHandlerMapping并不是默认的查找处理器方法的策略,他是通过    < mvc:annotation-driven /> 配置完成容器注册的
 

    推荐阅读