上一篇博客SpringMVC源码分析--容器初始化(四)FrameworkServlet我们已经了解到了SpringMVC容器的初始化,SpringMVC对容器初始化后会进行一系列的其他属性的初始化操作,在SpringMVC初始化完成之后会调用onRefresh(wac)方法,它通过模板方式在子类DispatcherServlet中实现的。
onRefresh函数实现如下,其具体的实现就放到initStrategies函数中实现。
/** * This implementation calls {@link #initStrategies}. */ //初始化策略,完成SpringMVC默认实现类的初始化,onRefresh是在父类FrameworkServlet中调用 @Override protected void onRefresh(ApplicationContext context) { initStrategies(context); }
initStrategies函数中初始化了一些springMVC运行过程中需要使用的默认的实现类,接下来我们分别介绍一下默认实现的 类。
//初始化SpringMVC的一些策略,也是springMVC主要的组件 protected void initStrategies(ApplicationContext context) { initMultipartResolver(context);//文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析 initLocaleResolver(context);//本地化解析 initThemeResolver(context);//主题解析 initHandlerMappings(context);//通过HandlerMapping,将请求映射到处理器 initHandlerAdapters(context);//通过HandlerAdapter支持多种类型的处理器 initHandlerExceptionResolvers(context);//如果执行过程中遇到异常,将交给HandlerExceptionResolver来解析 initRequestToViewNameTranslator(context);//直接解析请求到视图名 initViewResolvers(context);//通过viewResolver解析逻辑视图到具体视图实现 initFlashMapManager(context);//flash映射管理器 }
initMultipartResolver初始化文件上传解析器,与文件上传的相关的操作,有关文件上传操作我们会仔细分析,这里不做过多介绍。
////文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析 private void initMultipartResolver(ApplicationContext context) { try { //bean id被写死,在配置的时候需要注意,文件上传时需要注入bean名称为multipartResolver的类 this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class); if (logger.isDebugEnabled()) { logger.debug("Using MultipartResolver [" + this.multipartResolver + "]"); } } catch (NoSuchBeanDefinitionException ex) { // Default is no multipart resolver. this.multipartResolver = null; if (logger.isDebugEnabled()) { logger.debug("Unable to locate MultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME + "': no multipart request handling provided"); } } }
initLocaleResolver是初始化一些多语言实现相关的类,在配置多语言本地化时会注入bean名称为localeResolver,默认实现的类有FixedLocaleResolver ,SessionLocaleResolver ,CookieLocaleResolver, AcceptHeaderLocaleResolver
//本地化解析,支持web应用程序国际化,在springMVC应用程序中,用户的区域是通过区域解析器事变的 //spring采用的是默认区域解析器 AcceptHeaderLocaleResolver ,通过检验HTTP请求的accept-language头部来解析区域 //这个头部是有用户的浏览器根据底层操作系统的区域设置进行设定,这个区域解析器无法改变用户的区域,因为无法修改用户 //操作系统的区域设置 private void initLocaleResolver(ApplicationContext context) { try { //在配置多语言本地化时会注入bean名称为localeResolver,默认实现的类有FixedLocaleResolver ,SessionLocaleResolver ,CookieLocaleResolver, AcceptHeaderLocaleResolver this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class); if (logger.isDebugEnabled()) { logger.debug("Using LocaleResolver [" + this.localeResolver + "]"); } } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. this.localeResolver = getDefaultStrategy(context, LocaleResolver.class); if (logger.isDebugEnabled()) { logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME + "': using default [" + this.localeResolver + "]"); } } }
initThemeResolver与样式相关的解析器,需要在配置文件中注入bean名称为themeResolver的,FixedThemeResolver, SessionThemeResolver和CookieThemeResolver
//动态样式支持 private void initThemeResolver(ApplicationContext context) { try { //需要在配置文件中注入bean名称为themeResolver的,FixedThemeResolver, SessionThemeResolver和CookieThemeResolver this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class); if (logger.isDebugEnabled()) { logger.debug("Using ThemeResolver [" + this.themeResolver + "]"); } } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. 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 + "]"); } } }
initHandlerMappings初始化HandlerMapping,HandlerMapping的工作就是为每个请求找到合适的请求找到一个处理器handler
//会加载HandlerMapping,默认使用BeanNameUrlHandlerMapping private void initHandlerMappings(ApplicationContext context) { this.handlerMappings = null; if (this.detectAllHandlerMappings) { // Find all HandlerMappings in the ApplicationContext, including ancestor contexts. //默认加载所有的HandlerMapping, Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { //数组中含有多个HandlerMapping this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values()); // We keep HandlerMappings in sorted order. AnnotationAwareOrderComparator.sort(this.handlerMappings); } } else { try { HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); this.handlerMappings = Collections.singletonList(hm); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerMapping later. } } // Ensure we have at least one HandlerMapping, by registering // a default HandlerMapping if no other mappings are found. if (this.handlerMappings == null) { this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default"); } } }
initHandlerAdapters是初始化HandlerAdapter,HandlerAdapter是真正调用Controller操作的类
//初始化HandlerAdapters,默认使用的是SimpleControllerHandlerAdapter private void initHandlerAdapters(ApplicationContext context) { this.handlerAdapters = null; if (this.detectAllHandlerAdapters) { // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts. Map<String, HandlerAdapter> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false); if (!matchingBeans.isEmpty()) { //数组中含有多个HandlerAdapters this.handlerAdapters = new ArrayList<HandlerAdapter>(matchingBeans.values()); // We keep HandlerAdapters in sorted order. AnnotationAwareOrderComparator.sort(this.handlerAdapters); } } else { try { HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class); this.handlerAdapters = Collections.singletonList(ha); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerAdapter later. } } //如果没有设置HandlerAdapters,则获取默认的配置 if (this.handlerAdapters == null) { this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default"); } } }
initHandlerExceptionResolvers是初始化HandlerExceptionResolver,用来操作异常,接下来我们会对其进行详细分析
//初始化HandlerExceptionResolver private void initHandlerExceptionResolvers(ApplicationContext context) { this.handlerExceptionResolvers = null; if (this.detectAllHandlerExceptionResolvers) { // Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts. Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerExceptionResolvers = new ArrayList<HandlerExceptionResolver>(matchingBeans.values()); // We keep HandlerExceptionResolvers in sorted order. AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers); } } else { try { HandlerExceptionResolver her = context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class); this.handlerExceptionResolvers = Collections.singletonList(her); } catch (NoSuchBeanDefinitionException ex) { // Ignore, no HandlerExceptionResolver is fine too. } } // Ensure we have at least some HandlerExceptionResolvers, by registering // default HandlerExceptionResolvers if no other resolvers are found. if (this.handlerExceptionResolvers == null) { this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerExceptionResolvers found in servlet '" + getServletName() + "': using default"); } } }
initRequestToViewNameTranslator是初始化到ViewName的处理器。
/* 返回一个对应的视图名称*/ private void initRequestToViewNameTranslator(ApplicationContext context) { try { this.viewNameTranslator = context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class); if (logger.isDebugEnabled()) { logger.debug("Using RequestToViewNameTranslator [" + this.viewNameTranslator + "]"); } } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. this.viewNameTranslator = getDefaultStrategy(context, RequestToViewNameTranslator.class); if (logger.isDebugEnabled()) { logger.debug("Unable to locate RequestToViewNameTranslator with name '" + REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME + "': using default [" + this.viewNameTranslator + "]"); } } }
initViewResolvers初始化View的解析器
//初始化viewResolver private void initViewResolvers(ApplicationContext context) { this.viewResolvers = null; if (this.detectAllViewResolvers) { // Find all ViewResolvers in the ApplicationContext, including ancestor contexts. Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false); if (!matchingBeans.isEmpty()) { this.viewResolvers = new ArrayList<ViewResolver>(matchingBeans.values()); // We keep ViewResolvers in sorted order. AnnotationAwareOrderComparator.sort(this.viewResolvers); } } else { try { ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class); this.viewResolvers = Collections.singletonList(vr); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default ViewResolver later. } } // Ensure we have at least one ViewResolver, by registering // a default ViewResolver if no other resolvers are found. if (this.viewResolvers == null) { this.viewResolvers = getDefaultStrategies(context, ViewResolver.class); if (logger.isDebugEnabled()) { logger.debug("No ViewResolvers found in servlet '" + getServletName() + "': using default"); } } }
initFlashMapManager初始化FlashMapManager,与链接跳转相关的。
//初始化 FlashMapManager private void initFlashMapManager(ApplicationContext context) { try { this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class); if (logger.isDebugEnabled()) { logger.debug("Using FlashMapManager [" + this.flashMapManager + "]"); } } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class); if (logger.isDebugEnabled()) { logger.debug("Unable to locate FlashMapManager with name '" + FLASH_MAP_MANAGER_BEAN_NAME + "': using default [" + this.flashMapManager + "]"); } } }
这样就完成了SpringMVC工程启动时初始化的所有工作了,主要就是完成IOC容器的初始化和一些默认实现的初始化,这样就完成了SpringMVC的初始化工作,接下来就是对Controller的访问链接的处理,我们会一步一步的写源码博客进行分析的。