SpringMVC源碼解析,springmvc源碼

來源:互聯網
上載者:User

SpringMVC源碼解析,springmvc源碼

HandlerMethodArgumentResolver主要負責執行handler前參數準備工作.

看個例子,紅色部分的id初始化,填儲值就是它乾的活:

1     @RequestMapping(value = "/{id}")2     @ResponseBody3     public String getBook(@PathVariable("id") String id) {4         Hello helloProxy = new HelloProxy();5         helloProxy.say("Jack");6         7         return id;8     }

 

分析目錄:

  1. 介面定義(是否支援參數,處理參數)

  2. 代言人HandlerMethodArgumentResolverComposite,封裝其他實現

  3. 具體實現

    composite除外,根據是否實現HandlerMethodReturnValueHandle分為XXXMethodArgumentResolver(不實現)和XXXMethodProssor(實現)

    HandlerMethodReturnValueHandle用於處理傳回值.

    實作類別實在太多,簡單分析下各類的職責吧,具體內容看下面.

    

 

1. 介面定義

 老規矩,上來先看介面,看似很簡單,一個是否支援,一個處理.

 1 package org.springframework.web.method.support; 2 public interface HandlerMethodArgumentResolver { 3  4     /** 5      * 解析器是否支援參數 6      */ 7     boolean supportsParameter(MethodParameter parameter); 8  9     /**10      * 解析參數,填充到參數值11      */12     Object resolveArgument(MethodParameter parameter,13                            ModelAndViewContainer mavContainer,14                            NativeWebRequest webRequest,15                            WebDataBinderFactory binderFactory) throws Exception;16 17 }

 

2. 代言人HandlerMethodArgumentResolverComposite,封裝其他實現

通過封裝其他的實現,對外統一提供解析服務,這樣使用者在使用時,根本不用關心參數在哪裡怎麼解析處理的,只需要調用supportsParameter,resolveArgument就可以了.

而如果要擴充支援的類型也很簡單,添加實作類別,然後通過addResolver註冊進來就可以了.

看到這個怎麼想起設計模式的開閉原則了.對擴充開放,對修改關閉.

看點代碼:

封裝其他實現,並提供註冊功能

 1 package org.springframework.web.method.support; 2 public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver { 3     private final List<HandlerMethodArgumentResolver> argumentResolvers = 4             new LinkedList<HandlerMethodArgumentResolver>(); 5     public HandlerMethodArgumentResolverComposite addResolver(HandlerMethodArgumentResolver argumentResolver) { 6         this.argumentResolvers.add(argumentResolver); 7         return this; 8     } 9 10     public HandlerMethodArgumentResolverComposite addResolvers(11             List<? extends HandlerMethodArgumentResolver> argumentResolvers) {12         if (argumentResolvers != null) {13             for (HandlerMethodArgumentResolver resolver : argumentResolvers) {14                 this.argumentResolvers.add(resolver); // 難得沒調addResolver15             }16         }17         return this;18     }

在來看看具體是如何處理請求的:

都是都通過private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter)尋找resolver實現的.

  先用parameter當key去緩衝中取

  如果取不到迭代所有的reoslevers,一個個執行supportsParameter,直到有一個true.

  跟GOF的責任鏈設計模式定義一致.

 1 package org.springframework.web.method.support; 2 public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver { 3     public boolean supportsParameter(MethodParameter parameter) { 4         return getArgumentResolver(parameter) != null; 5     } 6     public Object resolveArgument( 7             MethodParameter parameter, ModelAndViewContainer mavContainer, 8             NativeWebRequest webRequest, WebDataBinderFactory binderFactory) 9             throws Exception {10 11         HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);12         return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);13     }14     private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {15         HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);16         if (result == null) {17             for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {18                 if (methodArgumentResolver.supportsParameter(parameter)) {19                     result = methodArgumentResolver;20                     this.argumentResolverCache.put(parameter, result);21                     break;22                 }23             }24         }25         return result;26     }27 }

 

3. 具體實現

實在太多了,先湊合看下各個類的職責吧,具體的分析後續在debug中做.

AbstractMessageConverterMethodArgumentResolver 使用HttpMessageConverter解析來自request body參數值的基類.

--AbstractMessageConverterMethodProcessor 添加傳回值處理,所以改名了

----HttpEntityMethodProcessor 解析參數時,只處理HttpEntity;處理傳回值時支援HttpEntity和ResponseEntity.

----RequestResponseBodyMethodProcessor 使用HttpMessageConverter解析@RequestBody參數;處理使用@ResponseBody的傳回值

--RequestPartMethodArgumentResolver 解析使用@RequestPart,@RequestParam註解的參數;MultipartFile和Part的子類參數

AbstractNamedValueMethodArgumentResolver 解析named vlaue型別參數(其實就是索引值對).

--AbstractCookieValueMethodArgumentResolver 解析使用@CookieValue註解的參數

----ServletCookieValueMethodArgumentResolver 從HttpServletRequest中解析出cookie值

--ExpressionValueMethodArgumentResolver 解析@Value註解的參數

--MatrixVariableMethodArgumentResolver 解析@MatrixVariable註解的參數,不包括map類型

--PathVariableMethodArgumentResolver 解析使用@PathVariable註解的參數,從uri中解析參數

--RequestHeaderMethodArgumentResolver 解析使用@RequestHeader註解的參數,不包括map類型

--RequestParamMethodArgumentResolver 解析從request流中擷取值的參數,如@RequestParam,MultipartFile,Part,預設使用時解析基本參數.

AbstractWebArgumentResolverAdapter 使用@WebArgumentResolver的基類,用於向後相容.適配WebArgumentResolver

--ServletWebArgumentResolverAdapter 建立NativeWebRequest--

ErrorsMethodArgumentResolver 處理Errors子類參數

MapMethodProcessor 處理map型別參數

MatrixVariableMapMethodArgumentResolver 使用@MatrixVariable註解的map型別參數

ModelAttributeMethodProcessor 解析使用@ModelAttribute註解參數

--ServletModelAttributeMethodProcessor 使用ServletRequestDataBinder解析參數

ModelMethodProcessor 處理model型別參數

PathVariableMapMethodArgumentResolver 處理使用@PathVariable註解的map參數

RedirectAttributesMethodArgumentResolver 處理RedirectAttributes型別參數

RequestHeaderMapMethodArgumentResolver 處理使用@RequestHeader註解的map參數

RequestParamMapMethodArgumentResolver 處理使用@RequestParam註解的map參數

ServletRequestMethodArgumentResolver 處理request相關的參數:WebRequest,ServletRequest,MultipartRequest,HttpSession,Principal,Locale,InputStream,Reader

ServletResponseMethodArgumentResolver 解析response相關的參數:ServletResponse,OutputStream,Writer

SessionStatusMethodArgumentResolver 處理SessionStatus型別參數

UriComponentsBuilderMethodArgumentResolver 處理UriComponentsBuilder型別參數

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.