享读SpringMVC源码3-既有HandlerMapping 何生HandlerAdapter

永远别放弃本身,哪怕全部人都放弃了你java

1.既生瑜何生亮2.HandlerAdapter实现HttpRequestHandlerAdapterSimpleControllerHandlerAdapterSimpleServletHandlerAdapterRequestMappingHandlerAdapter3.总结:web

1.既生瑜何生亮

经过前几篇文章,咱们知道根据url能够从HandlerMapping中,获取到咱们须要的handler了。有了handler不就能够处理程序了吗。spring

为啥有了HandlerMapping ,还须要HandlerAdapter?设计模式

来看看DispatcherServlet#doDispatch(request, response) 与 handler之间的问题浏览器

  1. Servlet入参就2个,可是handler 里各类各样的入参。尤为是咱们经常使用的@RequestMapping这种方式定义的,参数有个根据开发人员心情定
  2. handler返回类型多种多样,返回各类格式的数据类型。
  3. 4种handler定义方式,如何选择?

这种固定的Servlet规范与灵活的Handler之间就产生了冲突。缓存

因而乎伟大的设计模式上场,适配器模式的存在就是解决这种不兼容双方的。HandlerAdapter就是这个适配器微信

1.入参的匹配,返回值的复杂处理交给适配器去处理
2.Handler的选择问题,交给适配器去操心app

这也为咱们使用适配器模式提供了好的范本。ide

public interface HandlerAdapter {

    boolean supports(Object handler);

    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    long getLastModified(HttpServletRequest request, Object handler);
}
复制代码

HandlerAdapter中定义了三个方法:url

  • 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 HandlerAdapterOrdered {

    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


若是以为文章有用, 求点赞👍 求关注❤️ 求分享👥
若是本文任何错误,请批评指教,不胜感激 !

微信公众号:[源码行动]加我认识认识呗
我把本身写文章的定位是我的理解日记。由于每当我写文章时,我会集中注意力在知识点的理解与阐述上,这样会加深,增强对知识点的理解。

新的一年,我享读读源码,不求技术飞速提升,但求内心舒服

相关文章
相关标签/搜索