SpringMVC源码阅读-dispatcher组件初始化过程(三)
说明
前面我们看到了是dispatcher负责组件的初始化
调用链:
org.springframework.web.servlet.HttpServletBean#init
->
org.springframework.web.servlet.FrameworkServlet#initServletBean
->
org.springframework.web.servlet.FrameworkServlet#initWebApplicationContext
->
org.springframework.web.servlet.DispatcherServlet#onRefresh
protected void onRefresh(ApplicationContext context) { this.initStrategies(context); } /** * 初始化spring mvc组件 * @param context */ protected void initStrategies(ApplicationContext context) { //<1>初始化上传文件Resolver this.initMultipartResolver(context); //<2>初始化国际化Resolver 不同区域显示不同视图 this.initLocaleResolver(context); //<3>初始化控制页面主题的Resolver this.initThemeResolver(context); //<4>初始化url映射 mapping this.initHandlerMappings(context); //<5>初始化Handler适配器 this.initHandlerAdapters(context); //<6>初始化全局异常处理HandlerExceptionResolver this.initHandlerExceptionResolvers(context);
//<7> this.initRequestToViewNameTranslator(context);
//<8> this.initViewResolvers(context);
//<9> this.initFlashMapManager(context); }
<1>initMultipartResolver
这个组件主要用于解析Content-Type
为 multipart/*
private void initMultipartResolver(ApplicationContext context) { try { //<1>从当前容器里面获取MultipartResolver实现类 this.multipartResolver = (MultipartResolver)context.getBean("multipartResolver", MultipartResolver.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Using MultipartResolver [" + this.multipartResolver + "]"); } } catch (NoSuchBeanDefinitionException var3) { this.multipartResolver = null; if (this.logger.isDebugEnabled()) { this.logger.debug("Unable to locate MultipartResolver with name 'multipartResolver': no multipart request handling provided"); } } }
主要处理请求头类型( Content-Type
)为 multipart/* 的请求
<1>
<!-- mulitipart --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8"/> <property name="maxUploadSize" value="5242880"/> </bean>
<2>initLocaleResolver
private void initLocaleResolver(ApplicationContext context) { try { this.localeResolver = (LocaleResolver)context.getBean("localeResolver", LocaleResolver.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Using LocaleResolver [" + this.localeResolver + "]"); } } catch (NoSuchBeanDefinitionException var3) { this.localeResolver = (LocaleResolver)this.getDefaultStrategy(context, LocaleResolver.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Unable to locate LocaleResolver with name 'localeResolver': using default [" + this.localeResolver + "]"); } } }
初始化国际化组件 使用例子:https://www.cnblogs.com/liukemng/p/3750117.html
<3>initThemeResolver
private void initThemeResolver(ApplicationContext context) { try { this.themeResolver = (ThemeResolver)context.getBean("themeResolver", ThemeResolver.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Using ThemeResolver [" + this.themeResolver + "]"); } } catch (NoSuchBeanDefinitionException var3) { this.themeResolver = (ThemeResolver)this.getDefaultStrategy(context, ThemeResolver.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Unable to locate ThemeResolver with name 'themeResolver': using default [" + this.themeResolver + "]"); } } }
<4>initHandlerMappings
private void initHandlerMappings(ApplicationContext context) { this.handlerMappings = null; //默认为true可以通过inin-parameter修改 前面容器初始化过程 BeanWapper if (this.detectAllHandlerMappings) { /** * 从容器获取HandlerMapping的实现类 * 这里会获取到 * org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping * org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping */ Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerMappings = new ArrayList(matchingBeans.values()); //这里会获取Mapping的的Order注解的value进行排序 AnnotationAwareOrderComparator.sort(this.handlerMappings); } } else { try { //直接获取容器名称为handlerMapping HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class); this.handlerMappings = Collections.singletonList(hm); } catch (NoSuchBeanDefinitionException var3) { ; } } //这里应该是获取默认的HandlerMapping if (this.handlerMappings == null) { this.handlerMappings = this.getDefaultStrategies(context, HandlerMapping.class); if (this.logger.isDebugEnabled()) { this.logger.debug("No HandlerMappings found in servlet '" + this.getServletName() + "': using default"); } } }
使用例子:https://blog.csdn.net/neweastsun/article/details/79213867
<5>initHandlerAdapters
适配器模式 因为conroller不止是@Controller还有可能是servlte 再或者我们自定义注解@MyController
private void initHandlerAdapters(ApplicationContext context) { this.handlerAdapters = null; /** * 默认为true 可以通过init-parameter修改 */ if (this.detectAllHandlerAdapters) { /** * 从容器获取HandlerAdapter 我这里获取到的是 * org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter * org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter * org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter */ Map<String, HandlerAdapter> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerAdapters = new ArrayList(matchingBeans.values()); //读取sort注解标签进行排序 AnnotationAwareOrderComparator.sort(this.handlerAdapters); } } else { try { //从容器获取id为handlerAdapter的 HandlerAdapter ha = (HandlerAdapter)context.getBean("handlerAdapter", HandlerAdapter.class); this.handlerAdapters = Collections.singletonList(ha); } catch (NoSuchBeanDefinitionException var3) { ; } } //加载默认额 if (this.handlerAdapters == null) { this.handlerAdapters = this.getDefaultStrategies(context, HandlerAdapter.class); if (this.logger.isDebugEnabled()) { this.logger.debug("No HandlerAdapters found in servlet '" + this.getServletName() + "': using default"); } } }
<6>initHandlerExceptionResolvers
用于全局捕获异常处理器
private void initHandlerExceptionResolvers(ApplicationContext context) { this.handlerExceptionResolvers = null; if (this.detectAllHandlerExceptionResolvers) { Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerExceptionResolvers = new ArrayList(matchingBeans.values()); AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers); } } else { try { HandlerExceptionResolver her = (HandlerExceptionResolver)context.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); this.handlerExceptionResolvers = Collections.singletonList(her); } catch (NoSuchBeanDefinitionException var3) { ; } } if (this.handlerExceptionResolvers == null) { this.handlerExceptionResolvers = this.getDefaultStrategies(context, HandlerExceptionResolver.class); if (this.logger.isDebugEnabled()) { this.logger.debug("No HandlerExceptionResolvers found in servlet '" + this.getServletName() + "': using default"); } } }
<7>initRequestToViewNameTranslator
ViewResolver是根据ViewName查找VIew,但有的Handler处理完后并没有设置View也没有ViewName,这时需要从request获取viewName,RequestToViewNameTranslator就是做这个事情。
private void initRequestToViewNameTranslator(ApplicationContext context) { try { this.viewNameTranslator = (RequestToViewNameTranslator)context.getBean("viewNameTranslator", RequestToViewNameTranslator.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Using RequestToViewNameTranslator [" + this.viewNameTranslator + "]"); } } catch (NoSuchBeanDefinitionException var3) { this.viewNameTranslator = (RequestToViewNameTranslator)this.getDefaultStrategy(context, RequestToViewNameTranslator.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator': using default [" + this.viewNameTranslator + "]"); } } }
<8>initViewResolvers
ViewResolver是根据ViewName查找VIew
private void initViewResolvers(ApplicationContext context) { this.viewResolvers = null; if (this.detectAllViewResolvers) { Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false); if (!matchingBeans.isEmpty()) { this.viewResolvers = new ArrayList(matchingBeans.values()); AnnotationAwareOrderComparator.sort(this.viewResolvers); } } else { try { ViewResolver vr = (ViewResolver)context.getBean("viewResolver", ViewResolver.class); this.viewResolvers = Collections.singletonList(vr); } catch (NoSuchBeanDefinitionException var3) { ; } } if (this.viewResolvers == null) { this.viewResolvers = this.getDefaultStrategies(context, ViewResolver.class); if (this.logger.isDebugEnabled()) { this.logger.debug("No ViewResolvers found in servlet '" + this.getServletName() + "': using default"); } } }
<9>initFlashMapManager
我们都知道,重定向时一般都是不传数据的,如果一定要传数据,只能在URL中拼接字符串来传递,但是通过拼接字符串有缺点,比如长度问题,安全问题
通过FlashManager异常发送
private void initFlashMapManager(ApplicationContext context) { try { this.flashMapManager = (FlashMapManager)context.getBean("flashMapManager", FlashMapManager.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Using FlashMapManager [" + this.flashMapManager + "]"); } } catch (NoSuchBeanDefinitionException var3) { this.flashMapManager = (FlashMapManager)this.getDefaultStrategy(context, FlashMapManager.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Unable to locate FlashMapManager with name 'flashMapManager': using default [" + this.flashMapManager + "]"); } } }