Spring MVC 中最核心的工作组件应该是其前端控制器DispatcherServlet了。而DispatcherServlet的工作,又建立在Spring MVC的9大策略组件之上。可以将Spring MVC想象成一个团队:DispatcherServlet是团队负责人,而9大策略组件可以被想象成9个队员,分别负责某一部分的职责,这样整个团队在DispatcherServlet的领导和协调下紧密配合,一起处理来自客户端的每个请求。
Spring MVC的9大策略组件分别是 :
MultipartResolverLocaleResolverThemeResolverHandlerMappingHandlerAdapterHandlerExceptionResolverRequestToViewNameTranslatorViewResolverFlashMapManager
而这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在相应的环节被应用起来协调完成整个请求的处理。
本文深入探讨SpringMVC框架中DispatcherServlet与九大策略组件的协作机制,重点分析HandlerMapping和HandlerAdapter的角色与功能,揭示关注点分离和单一职责原则在架构设计中的应用。
3443

被折叠的 条评论
为什么被折叠?



