由於星期一接到面試通知,和麪試官約好了星期四面試,所以這幾天沒更新完這系列的文章,面完試後立馬就把這個解決掉。通過這次面試,也讓我懂得了很多,知道了自己的一些不足之處,後面還要繼續下功夫好好的深入複習下去。這幾篇文章寫的我覺得還是不夠仔細,感興趣的還是建議自己去看看源碼。
第
11 章 —— 組件概覽
HandlerMapping
根據 request 找到對應的處理器 Handler 和 Interceptors。內部只有一個方法
1
|
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
|
HandlerAdapter
Handler 適配器,內部方法如下:
1 2 3
|
boolean supports(Object handler); ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; long getLastModified(HttpServletRequest request, Object handler);
|
HandlerExceptionResolver
根據異常設置 ModelAndView ,再交給 render 方法進行渲染。
1 2
|
ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex)
|
ViewResolver
用來將 String 類型的視圖名和 Locale 解析爲 View 類型的視圖。
1
|
View resolveViewName(String viewName, Locale locale) throws Exception;
|
它的一個實現類 BeanNameViewResolver,它重寫 resolveViewName 方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public View resolveViewName(String viewName, Locale locale) throws BeansException { ApplicationContext context = getApplicationContext(); if (!context.containsBean(viewName)) { if (logger.isDebugEnabled()) { logger.debug("No matching bean found for view name '" + viewName + "'"); } return null; } if (!context.isTypeMatch(viewName, View.class)) { if (logger.isDebugEnabled()) { logger.debug("Found matching bean for view name '" + viewName + "' - to be ignored since it does not implement View"); } return null; } return context.getBean(viewName, View.class); }
|
RequestToViewNameTranslator
獲取 request 中的視圖名。接口裏面也是隻有一個方法:
1
|
String getViewName(HttpServletRequest request) throws Exception;
|
LocaleResolver
用於從 request 解析出 Locale。
1 2 3 4 5 6
|
public interface LocaleResolver { Locale resolveLocale(HttpServletRequest request); void setLocale(HttpServletRequest request, HttpServletResponse response, @Nullable Locale locale); }
|
ThemeResolver
解析主題
1 2 3 4 5 6
|
public interface ThemeResolver { String resolveThemeName(HttpServletRequest request); void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName); }
|
在 RequestContext.java 文件中可以獲取主題:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public String getThemeMessage(String code, String defaultMessage) { return getTheme().getMessageSource().getMessage(code, null, defaultMessage, this.locale); } public Theme getTheme() { if (this.theme == null) { this.theme = RequestContextUtils.getTheme(this.request); if (this.theme == null) { this.theme = getFallbackTheme(); } } return this.theme; }
|
RequestContextUtils.getTheme() 方法:
1 2 3 4 5 6 7 8 9 10 11
|
public static Theme getTheme(HttpServletRequest request) { ThemeResolver themeResolver = getThemeResolver(request); ThemeSource themeSource = getThemeSource(request); if (themeResolver != null && themeSource != null) { String themeName = themeResolver.resolveThemeName(request); return themeSource.getTheme(themeName); } else { return null; } }
|
MultipartResolver
用於處理上傳請求,處理方法:將普通的 request 包裝成 MultipartHttpServletRequest
1 2 3 4 5 6 7 8
|
public interface MultipartResolver { boolean isMultipart(HttpServletRequest request); MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException; void cleanupMultipart(MultipartHttpServletRequest request); }
|
FlashMapManager
FlashMap 主要在 redirect 中傳遞參數,FlashMapManager 用來管理 FlashMap 的。
1 2 3 4 5 6 7
|
public interface FlashMapManager { @Nullable FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response); void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response); }
|
小結
介紹 Spring MVC 中九大組件的接口、作用、內部方法實現及作用進行了簡單的介紹,詳細的還需大家自己去看源碼。
總結
Spring
MVC 原理總結
本質是一個 Servlet,這個 Servlet 繼承自 HttpServlet。Spring MVC 中提供了三個層次的 Servlet:HttpServletBean、FrameworkServlet 和 DispatcherServlet。他們相互繼承, HttpServletBean 直接繼承自 Java 的 HttpServlet。HttpServletBean 用於將 Servlet 中的 Servlet 中配置的參數設置到相應的屬性中,FrameworkServlet 初始化了 Spring MVC
中所使用的 WebApplicationContext,具體處理請求的 9 大組件是在 DispatcherServlet 中初始化的,整個繼承圖如下:
原文鏈接:看透 Spring MVC 源代碼分析與實踐 —— Spring MVC 組件分析