SpringMVC的核心是九大组件,是这九大组件完成了SpringMVC主流程。
一、九大组件的初始化
先来回顾一下DIspatcherServlet的初始化过程:
1)寻找或创建一个新的SpringMVC容器
2)创建SpringMVC容器,并调用refresh来初始化容器
3)调用onRefresh方法初始化SpringMVC的九大组件
在初始化过程中会调用onRefresh方法初始化SpringMVC的九大组件,源码如下:
DispatcherServlet.java1 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 { this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class); if (logger.isDebugEnabled()) { logger.debug("Using ThemeResolver [" + this.themeResolver + "]"); } } catch (NoSuchBeanDefinitionException ex) { 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.properties1 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的。