精盡Spring MVC原始碼分析 - HandlerAdapter 元件(一)之 HandlerAdapter
阿新 • • 發佈:2020-12-17
> 該系列文件是本人在學習 Spring MVC 的原始碼過程中總結下來的,可能對讀者不太友好,請結合我的原始碼註釋 [Spring MVC 原始碼分析 GitHub 地址](https://github.com/liu844869663/spring-framework) 進行閱讀
>
> Spring 版本:5.2.4.RELEASE
>
> 該系列其他文件請檢視:[**《精盡 Spring MVC 原始碼分析 - 文章導讀》**](https://www.cnblogs.com/lifullmoon/p/14123963.html)
## HandlerAdapter 元件
HandlerAdapter 元件,處理器的介面卡。因為處理器 `handler` 的型別是 Object 型別,需要有一個呼叫者來實現 `handler` 是怎麼被執行。Spring 中的處理器的實現多變,比如使用者的處理器可以實現 Controller 介面或者 HttpRequestHandler 介面,也可以用 `@RequestMapping` 註解將方法作為一個處理器等,這就導致 Spring MVC 無法直接執行這個處理器。所以這裡需要一個處理器介面卡,由它去執行處理器
由於 HandlerMapping 元件涉及到的內容較多,考慮到內容的排版,所以將這部分內容拆分成了五個模組,依次進行分析:
- [**《HandlerAdapter 元件(一)之 HandlerAdapter》**](https://www.cnblogs.com/lifullmoon/p/14137467.html)
- **《HandlerAdapter 元件(二)之 ServletInvocableHandlerMethod》**
- **《HandlerAdapter 元件(三)之 HandlerMethodArgumentResolver》**
- **《HandlerAdapter 元件(四)之 HandlerMethodReturnValueHandler》**
- **《HandlerAdapter 元件(五)之 HttpMessageConverter》**
## HandlerAdapter 元件(一)之 HandlerAdapter
先來回顧一下在 `DispatcherServlet` 中處理請求的過程中哪裡使用到 HandlerMapping 元件,可以回到[**《一個請求的旅行過程》**](https://www.cnblogs.com/lifullmoon/p/14131862.html)中的 `DispatcherServlet` 的 `doDispatch` 方法中看看,如下:
```java
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;
// ... 省略相關程式碼
// <3> 獲得請求對應的 HandlerExecutionChain 物件(HandlerMethod 和 HandlerInterceptor 攔截器們)
mappedHandler = getHandler(processedRequest);
// ... 省略相關程式碼
// <4> 獲得當前 handler 對應的 HandlerAdapter 物件
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// ... 省略相關程式碼
// <6> 真正的呼叫 handler 方法,也就是執行對應的方法,並返回檢視
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// ... 省略相關程式碼
}
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [...");
}
```
通過遍歷 HandlerAdapter 元件們,判斷是否支援處理該 `handler` 處理器,支援則返回該 HandlerAdapter 元件。**注意**,這裡是通過一個一個的 HandlerAdapter 元件去判斷是否支援該處理器,如果支援則直接返回這個 HandlerAdapter 元件,不會繼續下去,所以獲取處理器對應 HandlerAdapter 元件是有一定的先後順序的,預設是HttpRequestHandlerAdapter -> SimpleControllerHandlerAdapter -> RequestMappingHandlerAdapter
> 本文涉及到的內容適中,可以先檢視我的**總結**
### HandlerAdapter 介面
`org.springframework.web.servlet.HandlerAdapter`介面,處理器的介面卡,去執行處理器,程式碼如下:
```java
public interface HandlerAdapter {
/**
* 是否支援該處理器
*/
boolean supports(Object handler);
/**
* 執行處理器,返回 ModelAndView 結果
*/
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
/**
* 返回請求的最新更新時間,如果不支援該操作,則返回 -1 即可
*/
long getLastModified(HttpServletRequest request, Object handler);
}
```
HandlerAdapter 介面的體系結構如下:
沒有特別多