1.既生瑜何生亮
通过前几篇文章,我们知道根据url可以从HandlerMapping中,获取到我们需要的handler了。有了handler不就可以处理程序了吗。
为啥有了HandlerMapping ,还需要HandlerAdapter?
来看看DispatcherServlet#doDispatch(request, response) 与 handler之间的问题
- Servlet入参就2个,但是handler 里各种各样的入参。尤其是我们常用的@RequestMapping这种方式定义的,参数有个根据开发人员心情定
- handler返回类型多种多样,返回各种格式的数据类型。
- 4种handler定义方式,如何选择?
这种固定的Servlet规范与灵活的Handler之间就产生了冲突。
于是乎伟大的设计模式上场,适配器模式的存在就是解决这种不兼容双方的。HandlerAdapter就是这个适配器
1.入参的匹配,返回值的复杂处理交给适配器去处理
2.Handler的选择问题,交给适配器去操心
这也为我们使用适配器模式提供了好的范本。
public interface HandlerAdapter { boolean supports(Object handler); ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; long getLastModified(HttpServletRequest request, Object handler); }
HandlerAdapter中定义了三个方法:
- supports: 用于判断当前适配器是否支持是否能够支持当前的handler的适配。也就是解决了Handler的选择问题
- handle() :真正调用Handler,适配的核心。帮我们解决参数,返回值等一些列周边问题
- getLastModified():获取当前请求的最后更改时间,主要用于供给浏览器判断当前请求是否修改过,从而判断是否可以直接使用之前缓存的结果
2.HandlerAdapter实现
针对不同的Handler,HandlerAdapter的实现也不同。
HttpRequestHandlerAdapter
public class HttpRequestHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof HttpRequestHandler); } @Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; } @Override public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; } }
看HttpRequestHandlerAdapter.supports 判断其是否是HttpRequestHandler接口类型,也就说HttpRequestHandlerAdapter适配org.springframework.web.HttpRequestHandler这种Handler
handle处理方法直接调用HttpRequestHandler实例的handleRequest方法
SimpleControllerHandlerAdapter
从supports方法可以看出适配的是实现Controller接口这种handler,handle处理方法也是直接调用Controller实例的handleRequest方法
public class SimpleControllerHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof Controller); } @Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); } }
SimpleServletHandlerAdapter
从supports方法可以看出适配的是Servlet这种handler,handle处理方法也是直接调用Servlet实例的service方法
public class SimpleServletHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof Servlet); } @Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((Servlet) handler).service(request, response); return null; } }
RequestMappingHandlerAdapter
最重要的HandlerAdapter,之所以说重要,因为他是最复杂,也是SpringMVC的核心功能之一。
看上文的其他三种handler适配器。都很简单。SpringMVC适配器的重头戏其实就在RequestMappingHandlerAdapter
我们先来看看其supports方法,其实现在父类AbstractHandlerMethodAdapter
中
public abstract class AbstractHandlerMethodAdapter { public final boolean supports(Object handler) { return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler)); } } public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter{ protected boolean supportsInternal(HandlerMethod handlerMethod) { return true; } }
可以看出,支持的是handler 是HandlerMethod类型,
handle 方法
的实现在其父类AbstractHandlerMethodAdapter 中,是个模板方法,调用子类RequestMappingHandlerAdapter#handleInternal方法
public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered { public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); } }
RequestMappingHandlerAdapter#handle方法是SpringMVC最复杂的一块。上文提到的handler入参的匹配,返回值的处理等等操作都在此适配中体现。
RequestMappingHandlerAdapter#handle方法的工作原理比较复杂,单开一篇文章讲讲。
3.总结:
HandlerAdapter适配器充当servlet 与 多样性的Handler 之间的调用的桥梁,把他们之间的参数匹配,返回值处理等问题解决掉了。 兼容是HandlerAdapter的工作。
所以:
- HandlerMapping ,负责解析登记Handler
- HandlerAdapter,负责兼容性调用
既要HandlerMapping 又要HandlerAdapter