SpringMVC源码分析-DispatcherServlet实例化干了些什么

上一篇:SpringMVC启动与Spring启动差别分析java

阅读这篇文章以前,请先按照模拟SpringBoot编写一个嵌套Tomcat的工具类(方便调试)完成环境的搭建web

思考

在开始看源码以前先作一下思考,好比:spring

1.SpringMVC既然能从Tomcat哪里接收请求,那么SpringMVC必定是提供了一个Servlet的,并且是由这个Servlet完成全部的请求和响应。tomcat

2.既然这个Servlet能够提供很是多的功能,并且和Spring相关,那么它应该持有某一种Spring的XxxApplicationContextmvc

3.有了Context,SpringMVC是否是还提供了很是多默认的类去实现复杂的功能,好比参数解析、参数绑定、返回值解析、视图解析等等app

 

有了上面的问题,下面带着问题去一个个验证。。。工具

经过官方文档或者百度或者本身开发经验应该知道有DispatcherServlet这个类。。。。是的,它就是SpringMVC传世纪的类,由它打通tomcat和Spring容器,并让咱们的Bean拥有Spring容器丰富多彩功能的权利。源码分析

类结构图

那么先分析DispacherServlet的类结构图spa

能够看到它是Servlet,ApplicationContextAware,EnvironmentAware的子类,那么应该有一下几个特性:.net

1.能被Tomcat识别与调用,调用的时候会先调用init方法,再调用doXxx方法

2.能够在DispatcherServlet中轻松的获取Context和Environment对象,并且由Spring完成它的实例化(尚待证明,等后面看SpringBoot源码来确认)

源码分析

套路分析:类被实例化以前会先加载,类加载的时候会执行类变量初始化、静态块。因此先看看DispatcherServlet及其父类是否有静态块要执行。。。答案是有

DispatcherServlet的静态块

static {
		// Load default strategy implementations from properties file.
		// This is currently strictly internal and not meant to be customized
		// by application developers.
		/**
		 * 从DispatcherServlet.properties(此文件在webmvc工程下)当中加载默认的strategy(有道翻译:策略)
		 * SpringMVC官方说:这些类是核心的东西,不容许让普通开发者进行自定义,固然以为本身牛逼也是能够上
		 */
		try {
			/**
			 * 将在DispatcherServlet.class路径下的DispatcherServlet.properties文件包装到一个ClassPathResource当中
			 */
			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
			/**
			 * 从DispatcherServlet.properties文件中把配置信息加载为Properties对象,里面包含了以下几大部分
			 * LocaleResolver/ThemeResolver/HandlerMapping/HandlerAdapter/HandlerExceptionResolver/RequestToViewNameTranslator/
			 * ViewResolver/FlashMapManager
			 */
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
		}
	}

简单说明一下:

DispatcherServlet.properties当中配置的类都是很是重要的,不要动它们,它们最终都是有Spring完成实例化,因此咱们能够写XxxPostProcessor对它们的实例化进行干预,实现一些自定义的功能。

看看配置文件里面的内容,时刻牢记一点,它们很重要,后面DEBUG看到的类几乎都是经过它们带出来的,由于实例化它们的时候,由会默认弄出不少resolver出来。而后根据不一样参数去匹配不一样的resolver完成入参、出参、映射等等功能。

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.function.support.RouterFunctionMapping

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.function.support.HandlerFunctionAdapter


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

另外还设置了不少类变量的默认值,在此不去分析每个变量的做用,工做量太庞大了。

DispatcherSerlvet实例化

构造方法的执行与成员变量初始化

构造方法

public DispatcherServlet(WebApplicationContext webApplicationContext) {
		super(webApplicationContext);
		setDispatchOptionsRequest(true);
	}

将Spring的上下文与DispatcherServlet关联起来,而且将dispatchOptionsRequest设置为true,它的做用是开启Servlet是否能够处理http的options

 

下一篇:SpringMVC源码分析-DispatcherServlet的Init

相关文章
相关标签/搜索