Spring源码分析(9)——SpringMVC九大组件

SpringMVC的核心是九大组件,是这九大组件完成了SpringMVC主流程。

一、九大组件的初始化

先来回顾一下DIspatcherServlet的初始化过程:

1)寻找或创建一个新的SpringMVC容器

2)创建SpringMVC容器,并调用refresh来初始化容器

3)调用onRefresh方法初始化SpringMVC的九大组件

在初始化过程中会调用onRefresh方法初始化SpringMVC的九大组件,源码如下:

DispatcherServlet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}

这九个方法的初始化方式都大同小异,就随便挑一个出来举例吧,以initThemeResolver()为例,这个方法会初始化ThemeResolver。从源码可以看到,在初始化过程中,主要经历了如下两步:

1)从SpringMVC容器中寻找ThemeResolver这个Bean,如果找到则放到变量中。因为refresh方法已经实例化了所有Bean,所以这里寻找到的ThemeResolver也是一个Bean。

2)如果没有找到,则使用默认的ThemeResolver。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void initThemeResolver(ApplicationContext context) {
try {
// 按Bean名字从容器中寻找ThemeResolver
this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ThemeResolver [" + this.themeResolver + "]");
}
}
catch (NoSuchBeanDefinitionException ex) {
// 如果没有找到,则使用默认的ThemeResolver
this.themeResolver = getDefaultStrategy(context, ThemeResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ThemeResolver with name '" + THEME_RESOLVER_BEAN_NAME +
"': using default [" + this.themeResolver + "]");
}
}
}

可以看一下这个组件的默认类型来源,这个组件默认类型定义在DispatcherServlet.properties中,ThemeResolver的默认类型是FixedThemeResolver。

DispatcherServlet.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

二、九大组件预览

HandlerMapping

HandlerMapping的作用是根据request找到相应的处理器Handler和Interceptors。

HandlerAdapter

HandlerAdapter前面说过,可以理解为会使用工具的人,它能调用具体的Handler。毕竟Handler可能是一个方法,也可能是一个类,或者是其他的方式,使用HandlerAdapter给开发者提供了极大的自由。

HandlerExceptionResolver

用于解析请求处理过程中产生的异常,根据异常设置ModelAndView,然后交给render方法进行渲染。

ViewResolver

用于将String类型的视图名和Locale解析为View类型的视图。例如FreeMarkerViewResolver解析Freemarker视图,InternalResourceViewResolver针对jsp视图。

RequestToViewNameTranslator

ViewResolver是根据ViewName查找View,担忧的Handler处理完后并没有设置View也没有设置viewName,这时就需要从request获取viewName了。

LocaleResolver

LocaleResolver用于从request解析出Locale,Locale就是zh-cn之类的,表示一个区域,有了它就可对不同区域的用户显示不同的结果。

ThemeResolver

ThemeResolver作用主要用于从request解析出主题名。

MultipartResolver

用于处理上传请求,处理方法是将普通的request包装成MultipartHttpServletRequest,后者可以直接调用getFile方法获取到File。

FlashMapManager

FlashMap用于在redirect中传递参数,而FlashMapManager是用来管理FlashMap的。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×