spring學習筆記之AbstractController源碼解讀

Spring 學習筆記(二)-- AbstactController

控制器是 MVC 設計模式的一部分,通過定義服務接口提供對應用行爲的訪問。控制器獲取用戶輸入的數據並作簡單的轉換處理成符合服務模塊的規則並傳入服務模塊,經過服務模塊的處理給用戶返回視圖。 Spring 的控制器以抽象的方式實現了這種概念,並且有很多樣的控制器在不同情況下可供使用,包括了確定視圖的控制器,基於命令的控制器,還有執行嚮導式邏輯的控制器,在這裏僅舉幾個例子。

Spring 的控制器結構的基礎是 org.springframework.web.servlet.mvc.Controller 接口。

可以看到, Controller 接口定義了一個方法,負責處理一個請求並通過合適的模塊返回視圖。在 Spring 通過 ModelAndView 和 Controller 實現。 Controller 接口是非常抽象的, Spring 提供許多實現了這個接口的控制器,這些控制器包含了許多功能,在你需要的時候可以使用。而 Controller 接口只是定義了一個方法負責最基本的職責。

Spring 定義的控制器並不是直接實現 Controller 接口,而是實現了 AbstractController,AbstractorController 實現了 Controller 接口。

下面表格是 AbstractController 提供的功能點。

Feature

說明

supportMethods

表明控制器會接收哪些方法。一般會默認設置GET 和POST ,你也可以修改這些方法。如果一個請求攜帶的方法是這個控制器不支持的,客戶端會被告知,拋出ServletException 。

requireSession

表明控制器是否需要HTTP session 。

synchronizeOnSession

確定是否對HTTP session 實行同步。

cacheSeconds

設置cache 時間。默認是-1 ,則不設置。

useExpiresHeader

爲了與HTTP1.0 的‘Expires’ 兼容. 默認true

useCacheHeader

爲了與HTTP1.0 的‘Cache-Control’ 兼容,默認true

當你用 AbstractController 作爲你控制器的父類的時候,你只需要改寫 handleRequestInternal(HttpServletRequest, HttpServletResponse) 方法,實現業務邏輯,並返回 ModelAndView 對象。下面是一個下面是一個例子。

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

上面這個控制器產生了 cache 指令告訴客戶端 cache 保持 2 分鐘。我們看到一個編碼的壞習慣,就是返回視圖的時候用了硬編碼。

上面講到的是從 spring-reference.pdf 翻譯過來的,部分加上自己的理解。現在再結合源碼可以更深入的瞭解到上面的機制是怎麼運行的。

首先我們現看一下 AbstractController 的類層次圖。

AbstractController class hierarchy

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

似比較複雜。一步一步來看。

現看 AbstractController 類。 Spring 定義的所有控制器都繼承於它。它有一個屬性

private boolean synchronizeOnSession = false ;

這個屬性的作用在上面有提到過。上面提到的其他屬性在 AbstractController 的父類定義。

另外就是實現了 Controller 接口的方法:

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

首先是委託 WebContentGenerator 作一些準備的工作。作一些什麼樣的工作呢?我們再看 WebContentGenerator checkAndPrepare () 方法。注意一下, WebContentGenerator 初始化時將默認的處理方法爲 get,post,head 。代碼如下:

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

restrictDefaultSupportedMethods 默認爲 true

this . useExpiresHeader 處理根據上文知道是爲了兼容 HTTP1.0.

this . useCacheControlHeader 如果用戶有使用 cache 指令,則進行處理,用 Servlet 最基本的 response 設置。


<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

這段代碼結合上文就可以很好的理解 supportMethods 拋出異常的相關情況。

applyCacheSeconds(response,cacheSeconds,lastModified) 方法中,參數 lastModified 是在 ApplicationController handleRequest() ,有這樣傳入 this instanceof LastModified ,判斷這個控制類是否實現了 LastModified 接口 , 在這個方法實際上作了 cacheSeconds 屬性的工作。

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

常量 HEADER_CACHE_CONTROL =“ Cache-Control” ,這是對 cache 的處理。


現在回到 AbstractController handleRequests() 方法, checkAndPrepare ()處理完之後,再根據 synchronizeOnSession 判斷是否需要同步。 handleRequestInternal(request, response) 方法是真正處理邏輯的地方,這也是前面一個例子爲什麼要重寫這個方法的原因。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章