上一篇博客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的访问链接的处理,我们会一步一步的写源码博客进行分析的。







SpringMVC源码分析--容器初始化(五)DispatcherServlet的更多相关文章

  1. springMVC源码分析--容器初始化(二)DispatcherServlet

    在上一篇博客springMVC源码分析--容器初始化(一)中我们介绍了spring web初始化IOC容器的过程,springMVC作为spring项目中的子项目,其可以和spring web容器很好 ...

  2. SpringMVC源码分析--容器初始化(四)FrameworkServlet

    在上一篇博客SpringMVC源码分析--容器初始化(三)HttpServletBean我们介绍了HttpServletBean的init函数,其主要作用是初始化了一下SpringMVC配置文件的地址 ...

  3. SpringMVC源码分析--容器初始化(三)HttpServletBean

    在上一篇博客springMVC源码分析--容器初始化(二)DispatcherServlet中,我们队SpringMVC整体生命周期有一个简单的说明,并没有进行详细的源码分析,接下来我们会根据博客中提 ...

  4. springMVC源码分析--容器初始化(一)ContextLoaderListener

    在spring Web中,需要初始化IOC容器,用于存放我们注入的各种对象.当tomcat启动时首先会初始化一个web对应的IOC容器,用于初始化和注入各种我们在web运行过程中需要的对象.当tomc ...

  5. SpringMVC源码分析(3)DispatcherServlet的请求处理流程

    <springmvc源码分析(2)dispatcherservlet的初始化>初始化DispatcherServlet的多个组件. 本文继续分析DispatcherServlet解析请求的 ...

  6. springMVC源码分析--AbstractDetectingUrlHandlerMapping(五)

    上一篇博客springMVC源码分析--AbstractUrlHandlerMapping(三)中我们介绍了AbstractUrlHandlerMapping,主要介绍了一个handlerMap的ur ...

  7. springMVC源码分析--RequestMappingHandlerAdapter(五)

    上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...

  8. springMVC源码分析--DispatcherServlet请求获取及处理

    在之前的博客springMVC源码分析--容器初始化(二)DispatcherServlet中我们介绍过DispatcherServlet,是在容器初始化过程中出现的,我们之前也说过Dispatche ...

  9. springMVC源码分析--AbstractControllerUrlHandlerMapping(六)

    上一篇博客springMVC源码分析--AbstractDetectingUrlHandlerMapping(五)中我们介绍了AbstractDetectingUrlHandlerMapping,其定 ...

随机推荐

  1. 2015 多校联赛 ——HDU5386(暴力)

    Sample Input 1 3 5 2 2 1 2 3 3 2 1 3 3 3 3 3 3 3 3 3 3 H 2 3 L 2 2 H 3 3 H 1 3 L 2 3   Sample Output ...

  2. ●BZOJ 2251 [2010Beijing Wc]外星联络

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2251 题解: 后缀数组,倍增,RMQ 题意:把重复次数超过 1次的子串按字典序输出它们重复的 ...

  3. mycat 1.6 简单的操作实例

    环境: centos7.4 + mysql5.7.20 + mycat1.6单台主机上安装了5台mysql_5.7.20 实例(3306,3307,3308,3309,3310)3306为独立实例 ( ...

  4. 文本分类学习 (五) 机器学习SVM的前奏-特征提取(卡方检验续集)

    前言: 上一篇比较详细的介绍了卡方检验和卡方分布.这篇我们就实际操刀,找到一些训练集,正所谓纸上得来终觉浅,绝知此事要躬行.然而我在躬行的时候,发现了卡方检验对于文本分类来说应该把公式再变形一般,那样 ...

  5. VS2012中C++,#include无法打开自己所写的头文件(.h)

    最近刚开始学cocos2d-x,创建项目之后,自己按照<cocos2d-x 3.x 游戏开发>的教程写代码 先写了一个头文件  MyHelloWorldScene.h 然后在  AppDe ...

  6. 解决ansible首次连接host服务器需验证问题

    问题描述: [root@iZm5e79rtwsq2hm57teyk5Z ansible]# ansible aofeng -f 5 -m ping 47.93.18.191 | FAILED! =&g ...

  7. JSON概述

    错误理解:         一直以为JSON就是对象,拥有跟js对象类似的特征:{key:value}形式, 以至于在自己的思维定式中就出现了一种很可怕的情景:居然不知道怎么去解释习以为常的json是 ...

  8. WebService接口与HTTP接口的联系

    1 WebService有很多协议,为什么HTTP比较流行? WebService是个很重型的规范,它的应用协议是SOAP(简单对象访问协议),它所依赖的下层通信方式不单单是HTTP,也有SOAP o ...

  9. ORA-01207: file is more recent than control file - old control file的处理方法

    1. 连接数据库 sqlplus / as sysdba2. 启动数据库,此时会报标题中的错误startup 3.备份创建控制文件的脚本语句,并从中拷贝出相关的NORESETLOGS模式的创建控制文件 ...

  10. linux下的静态库与动态库详解

    静态库 先说说我们为什么需要库? 当有些代码我们大量会在程序中使用比如(scanf,printf等)这些函数我们需要在程序中频繁使用,于是我们就把这些代码编译为库文件,在需要使用时我们直接链接即可. ...