享讀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


若是以爲文章有用, 求點贊👍 求關注❤️ 求分享👥
若是本文任何錯誤,請批評指教,不勝感激 !

微信公衆號:[源碼行動]加我認識認識唄
我把本身寫文章的定位是我的理解日記。由於每當我寫文章時,我會集中注意力在知識點的理解與闡述上,這樣會加深,增強對知識點的理解。

新的一年,我享讀讀源碼,不求技術飛速提升,但求內心舒服

相關文章
相關標籤/搜索