SpringMVC 解析(一)概覽

御狐神發表於2022-01-11

Spring MVC是Spring提供的構建Web應用程式的框架,該框架遵循了Servlet規範,負責接收並處理Servelt容器傳遞的請求,並將響應寫回Response。Spring MVC以DispatcherServlet為核心,眾多元件如HandlerMapping為輔助,為使用者封裝了請求對映等底層邏輯,讓使用者可以更專注與業務邏輯的處理。本文會對Spring MVC整體結構做簡單介紹。

Spring MVC結構圖

Spring MVC是一個基於Servlet容器的Web應用框架,這裡的Servlet容器通常指Tomcat等服務容器。Servlet容器會負責監聽埠訊息並對映為Request/Response物件,然後交給Servlet例項去處理。SpringMVC框架的作用核心就是Servlet例項,這個例項在Spring中預設是DispatcherServlet,DispatcherServlet中使用眾多Spring元件來協助處理請求,其結構圖如下所示。

Spring MVC結構圖

Servlet容器

Servlet用於從某個Socket接收資料,並處理為標準的ServletRequest和ServletResponse。其內部邏輯比較複雜,我在關於Tomcat容器的其它系列文章中有詳細的介紹Tomcat的結構,此處只簡單列舉一下其功能:

  • 接收socket請求,可以是同步或者非同步,阻塞或非阻塞等方式。
  • 處理請求中的協議,如Http協議等。
  • 路由請求到對應的servelt例項。

Tomcat結構圖

核心元件DispatcherServlet

Spring MVC的核心元件就是DispatcherServlet,它是SpringWeb請求的排程中心,它的主要功能如下所示:

  • 在Spring容器啟動階段讀取對映規則,如RequestMapping;
  • 在請求到來的時候,按照載入的請求對映規則找到合適的處理方法;
  • 當處理請求的過程中出現了異常,對異常進行處理,如返回合適的介面或狀態碼;
  • 解析返回View的主題、時區等資訊;
  • 渲染返回的檢視。

DispatcherServlet功能圖

請求對映HandlerMapping

請求對映用於根據請求找到該請求需要呼叫的所有方法,包含過濾器和處理方法等。比較常用的一種請求對映是RequestMappingHandlerMapping,從名稱上可以看出來這個HandlerMapping是用於處理@RequestMapping註解請求對映的類。該類的工作原理如下所示,可以看到該類的主要作用是在收到請求之後,按順序拿到所有需要呼叫的方法(主要包含攔截器和處理方法),然後一一呼叫這些方法。

Handler Mapping原理

攔截器HandlerInterceptor

攔截器和Tomcat容器中的Valve有些類似,Spring的攔截器可以讓使用者靈活的在請求處理前、請求處理後和請求完成三個階段自定義操作,比如使用者許可權校驗等。攔截器的作用我們可以在上一節的圖中看到,Spring關於攔截器的介面定義如下所示:

public interface HandlerInterceptor {

    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
            @Nullable Exception ex) throws Exception {
    }

}

Hadler Interceptor

處理方法Handler

處理方法在DispatcherServlet定義為Object型別,如果我們使用了@RequestMapping來根據請求查詢處理方法,那麼查詢到的處理方法就是HandlerMethod型別,對應於Controller中新增了對應RequestMapping的方法。

Hadler

處理方法介面卡HandlerAdapter

DispatcherServlet從HandlerMapping中獲取到的處理方法是Object型別,意味著不同的處理方法可能返回不同的物件,DispatcherServlet本身是一個排程器,不應該關注如何呼叫不同的處理方法,所以Spring提供了HandlerAdapter列表使用者處理不同的排程方法。

// 處理方法介面卡介面定義
public interface HandlerAdapter {

    boolean supports(Object handler);

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

    long getLastModified(HttpServletRequest request, Object handler);

}

Hadler

異常處理HandlerExceptionResolver

HandlerExceptionResolver用於處理請求過程中出現的異常,其實現有很多中型別,不過我們日常開發中使用比較多的是ExceptionHandlerExceptionResolver,也就是處理我們定義的@ExceptionHandler註解。典型的@ExceptionHander的使用方式如下所示,@ExceptionHander還可以放在@ControllerAdvice註解的類中,表示對所有的Controller都會生效。

@Controller
public class SimpleController {

    // ...

    @ExceptionHandler
    public ResponseEntity<String> handle(IOException ex) {
        // ...
    }
}

總結

本文只是簡單的對SpingMVC的關鍵元件功能進行介紹,後續文章會對各個關鍵元件的原始碼進行解析。

qrcode_for_gh_83670e17bbd7_344-2021-09-04-10-55-16

本文最先發布至微信公眾號,版權所有,禁止轉載!

相關文章