DispatcherServlet中持有一个 List<HandlerMapping> 的组件,那么HandlerMapping究竟是什么东西呢?
我们通过debug的方式看看 handlerMappings 里面具体有什么?
可以看到这 handlerMappings 这个list里面一共有5个元素,这5个中有3个是WebMvcConfigurationSupportXXX类型的代理对象,另外2个是RequestMappingHandlerMapping和BeanNameUrlHandlerMapping。
我们看看官方文档上又是怎么说的,在https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-servlet 这个页面里有对HandlerMapping的说明。

从官方描述看,HandlerMapping是将请求与处理该请求的控制器(controller)、拦截器(intercepter)做了一个映射关系。对于一个请求,通过特定的HandlerMapping,就能找到需要用哪个controller的哪个方法来处理请求,并且处理这个请求需要执行哪些拦截器。这个寻找功能就是HandlerMapping接口中声明的HandlerExecutionChain getHandler(HttpServletRequest request)方法,该方法返回了一个叫 HandlerExecutionChain(处理器执行链)的实例,其中包装了控制器、拦截器列表这些数据。
1 | public interface HandlerMapping { |
通过debug的方式查看HandlerExecutionChain对象中封装的信息。

查看HandlerExecutionChain的源码可以看到它持有一个Object类型成员变量 handler ,它可能是一个HandlerMethod(封装了xxxController及请求对应的方法等)对象,也有可能是一个Controller对象、HttpRequestHandler 对象或Servlet对象,而这个 handler 具体是什么对象,是与所使用的 HandlerMapping 实现类有关。
前面也说到 DispatcherServlet 中的 handlerMappings 中有好几个不同的HandlerMapping实例,并且对于一个请求,会由其中的一个实例来获取到HandlerExecutionChain对象。
1 | /** |
那么,一个具体请求到底会通过哪个HandlerMapping实例来获取HandlerExecutionChain对象呢?这就又要回到官方文档里描述的,HandlerMapping接口的两个主要实现类是RequestMappingHandlerMapping和SimpleUrlHandlerMapping,它们两个分别用来处理SpringMVC中不同形式的url映射方式。
我们知道可以通过注解@Controller或@RestController注解方式来声明一个 Controller,然后使用@RequestMapping来修饰类或方法,这种方式其实是由RequestMappingHandlerMapping映射处理器来对请求进行映射的。也可以概括地说,RequestMappingHandlerMapping是专门支持@RequestMapping注解声明方式的请求映射处理器。

那么SimpleUrlHandlerMapping又用于处理哪种情况呢,那就是采用实现Controller接口或实现HttpRequestHandler接口的类,这种声明Controller的方式是早期的做法,现在在实际开发中用的很少了但是也是SpringMVC所支持的。
如下我们分别新建两个类分别实现Controller接口和实现HttpRequestHandler接口做具体的演示:
实现Controller接口的方式:

实现HttpRequestHandler接口的方式:

除了我们自己的实现,SpringMVC框架本身也有类实现了Controller接口等,比如:UrlFilenameViewController类、ServletForwardingController类等,但这些类的实例是需要我们通过配置去注入到IOC容器中。
有了上面的实现类,再进行debug,就可以验证前面对于RequestMappingHandlerMapping和SimpleUrlHandlerMapping的论述了,至此我们应该也就大概了解SpringMVC中的 HandlerMapping 是什么了。