《Spring MVC》 中剖析了 Spring MVC 工作原理,如下图:
从图中,可以知道请求处理的关键就是需要需要匹配到对应的处理器,即:根据请求 URL 匹配对应处理器 Handler
。Handler
结果如下
由 HandlerExecutionChain
嵌套着 HandlerMethod
。
即资源访问 URL 最终都对应着一个需要被执行的资源(即:简单理解就是Controller 声明的方法)。
如下图:存在两个资源
如何匹配确定最佳的执行资源,需要一套判定标准,在Spring MVC 中该规则由 RequestCondition
定义。
一、RequestCondition 介绍
RequestCondition 接口定义
RequestCondition<T>
接口定义了三个方法
T combine(T other)
和另一个条件合并T getMatchingCondition(HttpServletRequest request)
检查当前请求匹配条件和指定请求 Request 是否匹配,如果匹配返回相应的匹配条件,反之返回 null。**int **compareTo(T other, HttpServletRequest request)
**针对指定 reqeust 对比两个匹配条件,得到最佳匹配条件。RequestCondition 实现
类 | 描述 |
---|---|
AbstractRequestCondition<T> |
抽象父类,所有实现类都继承该类 |
CompositeRequestCondition |
组合模式,非具体实现。 |
PatternsRequestCondition |
路径匹配条件 |
RequestMethodsRequestCondition |
请求方法匹配条件 |
ParamsRequestCondition |
请求参数匹配条件 |
HeadersRequestCondition |
头部信息匹配条件 |
ConsumesRequestCondition |
可消费MIME匹配条件 |
ProducesRequestCondition |
可生成MIME匹配条件 |
二、简单分析
2.1、入口
如上述时序图,获取处理请求器的具体方法在AbstractHandlerMethodMapping#lookupHandlerMethod
中
2.2、简单分析
发起请求调用,请求资源 /api-version
,指定 header
version=v1`时,最佳匹配资源应该为 <br /><br />对应
HandlerMethod`获取源码如下:
关键两个逻辑
- 获取匹配条件
- 存在多个匹配时,对比得到最优解
具体逻辑入口
RequestMappingInfo#getMatchingCondition
获取匹配条件RequestMappingInfo#compareTo
对比两个匹配条件
比较顺序- 请求方法
- PatternsCondition 条件匹配
- ParamsCondition 条件匹配
- HeadersCondition 条件匹配
- ConsumesCondition 条件匹配
- ProducesCondition 条件匹配
- MethodsCondition 条件匹配
- CustomCondition 定制化条件匹配
具体细则略