Spring MVC
中最核心的工作组件应该是其前端控制器DispatcherServlet
了。而DispatcherServlet
的工作,又建立在Spring MVC
的9大策略组件之上。可以将Spring MVC
想象成一个团队:DispatcherServlet
是团队负责人,而9大策略组件可以被想象成9个队员,分别负责某一部分的职责,这样整个团队在DispatcherServlet
的领导和协调下紧密配合,一起处理来自客户端的每个请求。
Spring MVC
的9大策略组件分别是 :
MultipartResolver
LocaleResolver
ThemeResolver
HandlerMapping
HandlerAdapter
HandlerExceptionResolver
RequestToViewNameTranslator
ViewResolver
FlashMapManager
而这9大策略组件中,最重要的应该就是HandlerMapping
和HandlerAdapter
了。
HandlerMapping
抽象了请求URL
到请求处理器之间的映射,而HandlerAdapter
用于封装对请求处理器的真正调用。打个比方讲,当某个客户请求到达时,DispatcherServlet
会询问HandlerMapping
哪个请求处理器能处理,然后找到支持该请求处理器的HandlerAdapter
,然后将该请求处理器的调用交给该HandlerAdapter
完成。这个例子简单地描述了DispatcherServlet
处理请求工作的主流程,可以看出,DispatcherServlet
所做的事情很简单,可以认为仅仅是一个主流程,而无需关心底层细节。而这里面很重要的两个底层细节: 请求到请求处理器的映射关系,请求处理器如何处理请求的具体逻辑,都不是DispatcherServlet
关注点,相反,HandlerMapping
和HandlerAdapter
这两个队员承担了处理这些底层细节的角色,而且它们之间的分工很明确,可以协调配合却又不重叠。
不难看出,这正是软件开发中非常重要的架构设计原则的应用:“关注点分离"和"单一职责”。其实
Spring MVC
的其它7大策略组件也是应用这些架构设计原则的产物。通过应用这些架构原则,原本可能很复杂的一个Spring MVC
概念,就被分解成各个相对简单的各个组件了。
框架实现层面,HandlerMapping
和HandlerAdapter
首先是两个接口定义,如下所示。
HandlerMapping
接口
package org.springframework.web.servlet;
public interface HandlerMapping {
// 找到跟指定请求对应的请求处理器,封装为一个HandlerExecutionChain返回
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
HandlerAdapter
接口
package org.springframework.web.servlet;
public interface HandlerAdapter {
// 当前请求处理器适配器是否支持指定的请求处理器handler
boolean supports(Object handler);
// 针对给定的请求/响应对象request/response调用给定的请求处理器handler,
// 这里的handler一定符合条件 : this.supports(handler)==true
ModelAndView handle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception;
// 跟 HttpServlet 定义的getLastModified语义相同
long getLastModified(HttpServletRequest request, Object handler);
}
另外Spring MVC
框架自身提供了一些HandlerMapping
和HandlerAdapter
的实现类。这些实现类基本上能满足开发人员所有的各种请求/请求处理器的映射需求,一般无需开发人员另外提供自定义实现。
- 框架自身提供的
HandlerMapping
实现类
HandlerMapping 实现类 | 请求处理器类型 | 介绍 |
---|---|---|
RequestMappingHandlerMapping | HandlerMethod | 负责所有@RequestMapping 注解的控制器方法,映射关系 : url pattern => HandlerMethod |
SimpleUrlHandlerMapping | HttpRequestHandler /Controller | 负责设置进来映射关系:url pattern => HttpRequestHandler /Controller 实例 |
BeanNameUrlHandlerMapping | Controller | 负责检测所有实现了接口Controller 的bean : 每个这样的控制器类其实只有一个请求处理方法,映射关系 : url pattern => Controller bean |
- 框架自身提供的
HandleAdapter
实现类
HandleAdapter 实现类 | 请求处理器类型 | 介绍 |
---|---|---|
RequestMappingHandlerAdapter | HandlerMethod | 每个HandlerMethod 对应一个@RequestMapping 注解的控制器方法 |
HttpRequestHandlerAdapter | HttpRequestHandler | HttpRequestHandler 的例子比如静态资源请求处理器ResourceHttpRequestHandler ,一般通过ResourceHandlerRegistry 程序化配置进来 |
SimpleControllerHandlerAdapter | Controller | 请求处理器是实现了接口Controller 的某个对象 |
应用配置时,开发人员需要配置不同类型和目的的HandlerMapping
/HandlerAdapter
组件。可能通过属性文件,可能通过注解,也可能是通过代码直接配置。
当然,如果是基于
Spring boot
的Spring MVC
应用,框架提供了缺省的配置,如无额外需求,开发人员无需另外配置。
应用启动时,各种配置会被汇集起来,构建HandlerMapping
和HandlerAdapter
的组件bean
并注册到容器,这些组件bean
会基于HandlerMapping
和HandlerAdapter
的实现类。并最终会被DispatcherServlet
引用。
应用运行时,正如上面DispatcherServlet
主流程所描述的,HandlerMapping
和HandlerAdapter
组件bean
在相应的环节被应用起来协调完成整个请求的处理。