精盡Spring MVC原始碼分析 - HandlerAdapter 元件(二)之 ServletInvocableHandlerMethod
阿新 • • 發佈:2020-12-18
> 該系列文件是本人在學習 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》**](https://www.cnblogs.com/lifullmoon/p/14137483.html)
- **《HandlerAdapter 元件(三)之 HandlerMethodArgumentResolver》**
- **《HandlerAdapter 元件(四)之 HandlerMethodReturnValueHandler》**
- **《HandlerAdapter 元件(五)之 HttpMessageConverter》**
## HandlerAdapter 元件(二)之 ServletInvocableHandlerMethod
本文是接著[**《HandlerAdapter 元件(一)之 HandlerAdapter》**](https://www.cnblogs.com/lifullmoon/p/14137467.html)一文來分享 **ServletInvocableHandlerMethod** 元件。在 `HandlerAdapter` 執行處理器的過程中,主要的任務還是交由它來完成的。**ServletInvocableHandlerMethod** 封裝 `HandlerMethod` 處理器物件,它還包含 `HandlerMethodArgumentResolver` 引數解析器和 `HandlerMethodReturnValueHandler` 返回值處理器等元件。雖然內容不多,但還是有必要另一篇進行分析。
### 回顧
先來回顧一下 `RequestMappingHandlerAdapter` 是如何建立 **ServletInvocableHandlerMethod** 物件的,可以回到 [**《HandlerAdapter 元件(一)之 HandlerAdapter》**](https://www.cnblogs.com/lifullmoon/p/14137467.html) 中 **RequestMappingHandlerAdapter** 小節下面的 `invokeHandlerMethod` 方法,如下:
```java
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response,
HandlerMethod handlerMethod) throws Exception {
// ... 省略相關程式碼
// <4> 建立 ServletInvocableHandlerMethod 物件,並設定其相關屬性
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
// ... 省略相關程式碼
// <9> 執行呼叫
invocableMethod.invokeAndHandle(webRequest, mavContainer);
// ... 省略相關程式碼
}
protected ServletInvocableHandlerMethod createInvocableHandlerMethod(HandlerMethod handlerMethod) {
return new ServletInvocableHandlerMethod(handlerMethod);
}
```
- 將 `HandlerMethod` 處理器封裝成 ServletInvocableHandlerMethod 物件,然後設定引數解析器和返回值處理器
- 這裡設定了 ServletInvocableHandlerMethod 物件的 `resolvers`、`parameterNameDiscoverer` 和 `returnValueHandlers` 相關屬性
- 呼叫`invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs)`方法,執行處理器
### 類圖
ServletInvocableHandlerMethod 的整體類圖如下:
依次分析
### HandlerMethod
`org.springframework.web.method.HandlerMethod`,處理器的方法的封裝物件
在[**《HandlerMapping 元件(三)之 AbstractHandlerMethodMapping》**](https://www.cnblogs.com/lifullmoon/p/14137380.html)的 **AbstractHandlerMethodMapping** 小節中已經分析過該物件
### InvocableHandlerMethod
`org.springframework.web.method.support.InvocableHandlerMethod`,繼承 HandlerMethod 類,可 invoke 呼叫的 HandlerMethod 實現類。