SpringMVC源码分析4---DispatcherServlet如何找到正确的Controller

源码分析

在分析源码之前,我们先了解一下几个东西。

1.这个过程中重要的接口和类。

HandlerMethod类:

Spring3.1版本之后引入的。 是一个封装了方法参数、方法注解,方法返回值等众多元素的类。
  在这里插入图片描述
它的子类InvocableHandlerMethod有两个重要的属性WebDataBinderFactory和HandlerMethodArgumentResolverComposite, 很明显是对请求进行处理的。

InvocableHandlerMethod的子类ServletInvocableHandlerMethod有个重要的属性HandlerMethodReturnValueHandlerComposite,很明显是对响应进行处理的。

ServletInvocableHandlerMethod这个类在HandlerAdapter对每个请求处理过程中,都会实例化一个出来(上面提到的属性由HandlerAdapter进行设置),分别对请求和返回进行处理。  (RequestMappingHandlerAdapter源码,实例化ServletInvocableHandlerMethod的时候分别set了上面提到的重要属性)
在这里插入图片描述

MethodParameter类:

HandlerMethod类中的parameters属性类型,是一个MethodParameter数组。MethodParameter是一个封装了方法参数具体信息的工具类,包括参数的的索引位置,类型,注解,参数名等信息。

HandlerMethod在实例化的时候,构造函数中会初始化这个数组,这时只初始化了部分数据,在HandlerAdapter对请求处理过程中会完善其他属性,之后交予合适的HandlerMethodArgumentResolver接口处理。

以类DeptController为例:

@Controller
@RequestMapping(value = "/dept")
public class DeptController {
 
  @Autowired
  private IDeptService deptService;
  
  @RequestMapping("/update")
  @ResponseBody
  public String update(Dept dept) {
    deptService.saveOrUpdate(dept);
    return "success";
  }
  
}

(刚初始化时的数据)  
 在这里插入图片描述
 (HandlerAdapter处理后的数据)
 在这里插入图片描述

RequestCondition接口:

Spring3.1版本之后引入的。 是SpringMVC的映射基础中的请求条件,可以进行combine, compareTo,getMatchingCondition操作。这个接口是映射匹配的关键接口,其中getMatchingCondition方法关乎是否能找到合适的映射。
  在这里插入图片描述

RequestMappingInfo类:

Spring3.1版本之后引入的。 是一个封装了各种请求映射条件并实现了RequestCondition接口的类。

有各种RequestCondition实现类属性,patternsCondition,methodsCondition,paramsCondition,headersCondition,consumesCondition以及producesCondition,这个请求条件看属性名也了解,分别代表http请求的路径模式、方法、参数、头部等信息。
在这里插入图片描述

RequestMappingHandlerMapping类:

处理请求与HandlerMethod映射关系的一个类。

2.Web服务器启动的时候,SpringMVC到底做了什么。

先看AbstractHandlerMethodMapping的initHandlerMethods方法中。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述我们进入createRequestMappingInfo方法看下是如何构造RequestMappingInfo对象的。
在这里插入图片描述
PatternsRequestCondition构造函数:
在这里插入图片描述
类对应的RequestMappingInfo存在的话,跟方法对应的RequestMappingInfo进行combine操作。
在这里插入图片描述
然后使用符合条件的method来注册各种HandlerMethod。
在这里插入图片描述
下面我们来看下各种RequestCondition接口的实现类的combine操作。

PatternsRequestCondition:
在这里插入图片描述
在这里插入图片描述
RequestMethodsRequestCondition:

方法的请求条件,用个set直接add即可。

在这里插入图片描述
其他相关的RequestConditon实现类读者可自行查看源码。

最终,RequestMappingHandlerMapping中两个比较重要的属性

private final Map<T, HandlerMethod> handlerMethods = new LinkedHashMap<T, HandlerMethod>();

private final MultiValueMap<String, T> urlMap = new LinkedMultiValueMap<String, T>();

T为RequestMappingInfo。

构造完成。

我们知道,SpringMVC的分发器DispatcherServlet会根据浏览器的请求地址获得HandlerExecutionChain。

这个过程我们看是如何实现的。

首先看HandlerMethod的获得(直接看关键代码了):
在这里插入图片描述
这里的比较器是使用RequestMappingInfo的compareTo方法(RequestCondition接口定义的)。
在这里插入图片描述
然后构造HandlerExecutionChain加上拦截器
在这里插入图片描述

资源文件映射

以上分析均是基于Controller方法的映射(RequestMappingHandlerMapping)。

SpringMVC中还有静态文件的映射,SimpleUrlHandlerMapping。

DispatcherServlet找对应的HandlerExecutionChain的时候会遍历属性handlerMappings,这个一个实现了HandlerMapping接口的集合。

由于我们在*-dispatcher.xml中加入了以下配置:

<mvc:resources location="/static/" mapping="/static/**"/>

Spring解析配置文件会使用ResourcesBeanDefinitionParser进行解析的时候,会实例化出SimpleUrlHandlerMapping。
在这里插入图片描述
在这里插入图片描述
其中注册的HandlerMethod为ResourceHttpRequestHandler。

访问地址http://localhost:8888/SpringMVCDemo/static/js/jquery-1.11.0.js

在这里插入图片描述
在这里插入图片描述
地址匹配到/static/**。

最终SimpleUrlHandlerMapping找到对应的Handler -> ResourceHttpRequestHandler。

ResourceHttpRequestHandler进行handleRequest的时候,直接输出资源文件的文本内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值