Spring MVC 将 @RequestMapping
注解映射到对应的 Handler 方法的过程,主要由 RequestMappingHandlerMapping
这个类来完成。
1. RequestMappingHandlerMapping
的作用:
RequestMappingHandlerMapping
是 Spring MVC 中一个关键的HandlerMapping
实现。- 它负责维护一个请求映射表,该表存储了
RequestMappingInfo
对象与 Handler 方法(Controller 方法)之间的映射关系。 - 当
DispatcherServlet
接收到请求时,它会委托RequestMappingHandlerMapping
根据请求信息查找匹配的 Handler 方法。
2. RequestMappingHandlerMapping
的初始化:
RequestMappingHandlerMapping
实现了InitializingBean
接口,它的afterPropertiesSet()
方法会在 Spring 容器初始化时被调用。afterPropertiesSet()
方法会触发RequestMappingHandlerMapping
的初始化过程。
3. 扫描和注册映射关系:
- 扫描 Controller:
RequestMappingHandlerMapping
会扫描 Spring 容器中所有带有@Controller
或@RequestMapping
注解的 Bean。 - 遍历方法: 对于每个 Controller Bean,
RequestMappingHandlerMapping
会遍历该 Bean 中的所有方法。 - 解析
@RequestMapping
: 对于每个方法,RequestMappingHandlerMapping
会检查该方法上是否有@RequestMapping
注解(或其变体,如@GetMapping
、@PostMapping
等)。- 类级别
@RequestMapping
: 如果 Controller 类上也有@RequestMapping
注解,RequestMappingHandlerMapping
会将其与方法级别的@RequestMapping
注解进行合并。
- 类级别
- 创建
RequestMappingInfo
: 如果找到@RequestMapping
注解,RequestMappingHandlerMapping
会根据注解的属性值创建一个RequestMappingInfo
对象。RequestMappingInfo
包含了请求的匹配条件:- PatternsRequestCondition: 包含 URL 路径模式(支持 Ant 风格)。
- RequestMethodsRequestCondition: 包含 HTTP 请求方法(GET、POST 等)。
- ParamsRequestCondition: 包含请求参数条件。
- HeadersRequestCondition: 包含请求头条件。
- ConsumesRequestCondition: 包含请求的 Content-Type 条件。
- ProducesRequestCondition: 包含响应的 Content-Type 条件。
- CustomRequestCondition: 包含自定义的匹配条件(如果有)。
- 注册映射:
RequestMappingHandlerMapping
将创建好的RequestMappingInfo
对象与对应的 Handler 方法(HandlerMethod
对象)关联起来,并注册到内部的映射表中(Map<RequestMappingInfo, HandlerMethod>
)。
4. 请求匹配:
- 当
DispatcherServlet
接收到一个请求时,它会调用RequestMappingHandlerMapping
的getHandler()
方法。 getHandler()
方法会执行以下步骤:- 创建
HttpServletRequest
的包装类: 将HttpServletRequest
包装成一个ServletWebRequest
对象,方便后续处理。 - 获取请求信息: 从
HttpServletRequest
中获取请求的 URL、HTTP 方法、请求参数、请求头等信息。 - 遍历映射表: 遍历
RequestMappingHandlerMapping
内部维护的映射表(Map<RequestMappingInfo, HandlerMethod>
)。 - 匹配条件: 对于每个
RequestMappingInfo
,RequestMappingHandlerMapping
会将其中的匹配条件(PatternsRequestCondition
、RequestMethodsRequestCondition
等)与请求信息进行比较。 - 返回
HandlerExecutionChain
: 如果找到匹配的RequestMappingInfo
,RequestMappingHandlerMapping
会创建一个HandlerExecutionChain
对象,其中包含了匹配的 Handler 方法(HandlerMethod
)和相关的拦截器(如果有),并将其返回给DispatcherServlet
。 - 未找到匹配项: 如果没有找到匹配的
RequestMappingInfo
,RequestMappingHandlerMapping
会返回null
。
- 创建
5. 关键类和方法:
RequestMappingHandlerMapping
: 核心类,负责维护请求映射表,并根据请求查找匹配的 Handler 方法。RequestMappingInfo
: 包含了请求的匹配条件(URL、方法、参数、请求头等)。HandlerMethod
: 封装了 Controller 方法的信息(方法对象、所属的 Bean 对象等)。getHandler()
:RequestMappingHandlerMapping
的方法,根据请求查找匹配的HandlerExecutionChain
。afterPropertiesSet()
:RequestMappingHandlerMapping
的初始化方法,在 Spring 容器初始化时被调用,触发扫描和注册映射关系的过程。
总结:
RequestMappingHandlerMapping
通过扫描 @Controller
类和 @RequestMapping
注解,创建 RequestMappingInfo
对象,并将其与 Handler 方法关联起来,注册到内部的映射表中。当接收到请求时,RequestMappingHandlerMapping
会根据请求信息与 RequestMappingInfo
中的匹配条件进行比较,从而找到匹配的 Handler 方法,实现请求的路由和处理。