Spring MVC 是如何将 @RequestMapping 注解映射到对应的 Handler 方法?

发布于:2025-04-13 ⋅ 阅读:(27) ⋅ 点赞:(0)

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 接收到一个请求时,它会调用 RequestMappingHandlerMappinggetHandler() 方法。
  • getHandler() 方法会执行以下步骤:
    1. 创建 HttpServletRequest 的包装类:HttpServletRequest 包装成一个 ServletWebRequest 对象,方便后续处理。
    2. 获取请求信息:HttpServletRequest 中获取请求的 URL、HTTP 方法、请求参数、请求头等信息。
    3. 遍历映射表: 遍历 RequestMappingHandlerMapping 内部维护的映射表(Map<RequestMappingInfo, HandlerMethod>)。
    4. 匹配条件: 对于每个 RequestMappingInfoRequestMappingHandlerMapping 会将其中的匹配条件(PatternsRequestConditionRequestMethodsRequestCondition 等)与请求信息进行比较。
    5. 返回 HandlerExecutionChain 如果找到匹配的 RequestMappingInfoRequestMappingHandlerMapping 会创建一个 HandlerExecutionChain 对象,其中包含了匹配的 Handler 方法(HandlerMethod)和相关的拦截器(如果有),并将其返回给 DispatcherServlet
    6. 未找到匹配项: 如果没有找到匹配的 RequestMappingInfoRequestMappingHandlerMapping 会返回 null

5. 关键类和方法:

  • RequestMappingHandlerMapping 核心类,负责维护请求映射表,并根据请求查找匹配的 Handler 方法。
  • RequestMappingInfo 包含了请求的匹配条件(URL、方法、参数、请求头等)。
  • HandlerMethod 封装了 Controller 方法的信息(方法对象、所属的 Bean 对象等)。
  • getHandler() RequestMappingHandlerMapping 的方法,根据请求查找匹配的 HandlerExecutionChain
  • afterPropertiesSet() RequestMappingHandlerMapping 的初始化方法,在 Spring 容器初始化时被调用,触发扫描和注册映射关系的过程。

总结:

RequestMappingHandlerMapping 通过扫描 @Controller 类和 @RequestMapping 注解,创建 RequestMappingInfo 对象,并将其与 Handler 方法关联起来,注册到内部的映射表中。当接收到请求时,RequestMappingHandlerMapping 会根据请求信息与 RequestMappingInfo 中的匹配条件进行比较,从而找到匹配的 Handler 方法,实现请求的路由和处理。


网站公告

今日签到

点亮在社区的每一天
去签到