上一篇: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及其父类是否有静态块要执行。。。答案是有
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
另外还设置了不少类变量的默认值,在此不去分析每个变量的做用,工做量太庞大了。
构造方法的执行与成员变量初始化
构造方法
public DispatcherServlet(WebApplicationContext webApplicationContext) { super(webApplicationContext); setDispatchOptionsRequest(true); }
将Spring的上下文与DispatcherServlet关联起来,而且将dispatchOptionsRequest设置为true,它的做用是开启Servlet是否能够处理http的options
下一篇:SpringMVC源码分析-DispatcherServlet的Init