DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

DispatcherServlet如何找到正确的Controller(一)

前言

SpringMVC是目前主流的Web MVC框架之一。 

我们使用浏览器通过地址 http://ip:port/contextPath/path 进行访问,SpringMVC是如何得知用户到底是访问哪个Controller中的方法,这期间到底发生了什么。

本文将分析SpringMVC是如何处理请求与Controller之间的映射关系的,让读者知道这个过程中到底发生了什么事情。

本文实际上是在上文基础上,深入分析HandlerMapping里的

HandlerExecutionChain getHandler(HttpServletRequest var1) throws Exception;

该方法的具体实现,包括它如何找到对应的方法,以及如何把结果保存在map里,以便让请求转发到对应的handler上,同时也分析了handleradaptor具体做了什么事情。

源码分析

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

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

HandlerMethod类:

  Spring3.1版本之后引入的。 是一个封装了方法参数、方法注解,方法返回值等众多元素的类。图片[1]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

  它的子类InvocableHandlerMethod有两个重要的属性WebDataBinderFactory和HandlerMethodArgumentResolverComposite, 很明显是对请求进行处理的。

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

  ServletInvocableHandlerMethod这个类在HandlerAdapter对每个请求处理过程中,都会实例化一个出来(上面提到的属性由HandlerAdapter进行设置),分别对请求和返回进行处理。  (RequestMappingHandlerAdapter源码,实例化ServletInvocableHandlerMethod的时候分别set了上面提到的重要属性)图片[2]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

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";
  }

}

(刚初始化时的数据)  

图片[3]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

(HandlerAdapter处理后的数据)

图片[4]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

RequestCondition接口:

  Spring3.1版本之后引入的。 是SpringMVC的映射基础中的请求条件,可以进行combine, compareTo,getMatchingCondition操作。这个接口是映射匹配的关键接口,其中getMatchingCondition方法关乎是否能找到合适的映射。图片[5]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

RequestMappingInfo类:

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

  有各种RequestCondition实现类属性,patternsCondition,methodsCondition,paramsCondition,headersCondition,consumesCondition以及producesCondition,这个请求条件看属性名也了解,分别代表http请求的路径模式、方法、参数、头部等信息。图片[6]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

RequestMappingHandlerMapping类:

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

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

先看AbstractHandlerMethodMapping的initHandlerMethods方法中。

图片[7]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

图片[8]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

图片[9]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

我们进入createRequestMappingInfo方法看下是如何构造RequestMappingInfo对象的。

图片[10]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

PatternsRequestCondition构造函数:

图片[11]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

类对应的RequestMappingInfo存在的话,跟方法对应的RequestMappingInfo进行combine操作。

图片[12]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

然后使用符合条件的method来注册各种HandlerMethod。

图片[13]-DispatcherServlet如何找到正确的Controller(一)-Spring专区论坛-技术-SpringForAll社区

请登录后发表评论

    没有回复内容