由于星期一接到面试通知,和面试官约好了星期四面试,所以这几天没更新完这系列的文章,面完试后立马就把这个解决掉。通过这次面试,也让我懂得了很多,知道了自己的一些不足之处,后面还要继续下功夫好好的深入复习下去。这几篇文章写的我觉得还是不够仔细,感兴趣的还是建议自己去看看源码。
第 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 组件分析