一、HandlerMapping接口
总述
该接口是存放request请求与处理请求的handler映射关系的接口。SpringMVC提供了两个实现类:BeanNameUrlHandlerMapping和RequestMappingHandlerMapping。前者是默认使用的HandlerMapping。开发人员也可以自己定义实现此接口。
HandlerMapping实现类支持映射拦截器,但是不是必须要支持。处理请求的处理器handler总是被包装在HandlerExecutionChain实例中,可能伴随着HandlerInterceptor实例(因为HandlerMapping支持拦截器的映射)。也就是说,处理器handler如果前面有拦截器,则HandlerMapping会同时把拦截器映射进来。DispatcherServlet会按给定的顺序执行拦截器的preHandler方法,都返回true,最后调用处理器本身的方法。
参数化此映射功能是SpringMVC框架提供的强大的功能。其他的MVC框架都没有此功能。例如:
可以基于会话状态、cookie状态或许多其他变量编写自定义映射。(如何使用??)
接口方法
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
该接口只定义了一个方法,就是通过Request对象,获取到处理器handler对象和相应的拦截器。可以通过Request对象的URL,会话状态或一些其他属性的映射关系返回不同的处理器。此方法的返回值HandlerExecutionChain中包含着具体的处理器对象,处理器对象没有固定的规范接口约束,可以定义任何的处理器。例如,可以通过HandleAdapter适配另一种框架的处理器对象。
如果没有找到映射处理器,则返回null。HadnlerMapping的实现类可以有很多。当DispatcherServlet执行完所有的HandlerMapping实现类后,仍然返回null。则抛出异常。
二、HandlerExecutionChain类
上述讲到HandlerMapping的getHandler方法返回了HandlerExecutionChain对象。我们看HandlerExecutionChain的内部接口。
HandlerExecutionChain是一个类,包含了处理器和拦截器。我们看其几个重要的属性:
private final Object handler;
@Nullable
private HandlerInterceptor[] interceptors;
@Nullable
private List<HandlerInterceptor> interceptorList;
handler处理器是Object类型,这就是上面说到的接收任何类型的处理器。还维护了拦截器列表。下面我们看HandlerExecutionChain类的方法:
可以看到,该类的方法进行了拦截器方法的调用。
综上分析,Controller中的每个方法,都会生成一个HandlerExecutionChain类,里面封装着处理器和拦截器。
三、RequestMappingHandlerMapping类
RequestMappingHandlerMapping类也是HandlerMapping的实现类。这个类在源码中发挥了重要的作用,我们详细剖析一下这个类的源码。
先看其结构关系图:
重要的关系有两条,一条是InitializingBean线路,一条是HandlerMapping线路。需要注意的是HandlerMapping其实是两条路线。有一条路线和InitializingBean汇合了。
该类的主要特点是创建RequestMappingInfo对象。RequestMappingInfo对象里存放着详细的映射关系。所以,HandlerMapping其实就是个中介,它获取映射关系时,最终是从RequestMappingInfo对象中获取的映射关系,返回去的。所以,最终存放映射关系的类是RequestMappingInfo类。