(一)注册Spring监听器


org.springframework.web.SpringServletContainerInitializer#onStartup,其中参数webAppInitializerClasses是WebApplicationInitializer的子类.

循环WebApplicationInitializer 然后挨个onStartup 方法


先调用到org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#onStartup,

1.再调用父类
org.springframework.web.context.AbstractContextLoaderInitializer#onStartup调用
org.springframework.web.context.AbstractContextLoaderInitializer#registerContextLoaderListener调用
org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer#createRootApplicationContext
创建WebApplicationContext上下文(Spring上下文),在创建过程中会注册一个扫描器配置类,这个配置类带有@ComponentScan扫描Spring的Bean


然后在registerContextLoaderListener方法下面创建一个ContextLoaderListener,同时这个Listener绑定WebApplicationContext这个Spring上下文

最后 ServletContext添加ContextLoaderListener这个监听器.


(二)注册DispatcherServlet



Spring web 包下的 spi 路径
org.springframework.web.SpringServletContainerInitializer#onStartup(这个方法是Tomcat容器启动的时候调用的)

循环WebApplicationInitializer 调用onStartup 方法

org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#onStartup调用,初始化AnnotationConfigWebApplicationContext容器.


org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#registerDispatcherServlet
调用org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#createServletApplicationContext(
子类AbstractAnnotationConfigDispatcherServletInitializer) 方法内部实例化
org.springframework.web.context.support.AnnotationConfigWebApplicationContext,同时绑定扫描器配置类,扫描器配置类是一个回调,是用户自己定义的,这个扫描器类有
@ComponentScan 注解,用来加载SpringMVC容器的


调用到org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer#getServletConfigClasses
钩子方法,这个钩子方法扫描@Controller注解(注意!此时并没有启动)

然后
org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#registerDispatcherServlet
调用org.springframework.web.servlet.support.AbstractDispatcherServletInitializer#createDispatcherServlet来创建DispatcherServlet
然后下面的代码就是设置DispatcherServlet加入到Servlet容器,同时设置连接路径并且随着Servlet加载而加载等等配置(设置优先级为1,优先级越小越被先加载,同时设置Mapping路径为”/”,同时也设置异步支持).



Tomcat在容器启动的时候会调用init方法,DispatcherServlet的父类 org.springframework.web.servlet.HttpServletBean#init调用
org.springframework.web.servlet.HttpServletBean#initServletBean
org.springframework.web.servlet.FrameworkServlet#initServletBean调用
org.springframework.web.servlet.FrameworkServlet#initWebApplicationContext调用
org.springframework.web.servlet.FrameworkServlet#configureAndRefreshWebApplicationContext 调用
org.springframework.context.ConfigurableApplicationContext#refresh 完成SpringMVC容器的加载



(三)初始化Spring容器


然后tomcat会在org.apache.catalina.core.StandardContext#listenerStart方法调用javax.servlet.ServletContextListener#contextInitialized来启动

org.springframework.web.context.ContextLoaderListener#contextInitialized,调用
org.springframework.web.context.ContextLoader#initWebApplicationContext调用
org.springframework.web.context.ContextLoader#configureAndRefreshWebApplicationContext调用
org.springframework.context.ConfigurableApplicationContext#refresh (AbstractApplicationContext的refresh)完成Spring容器的初始化



(四)初始化SpringMVC容器


在Tomcat容器启动的时候,由于要遵循Servlet规范, 就会调用ContextLoaderListener的 contextInitialized方法,这个方法是Tomcat调用的. 这个contextInitialized方法内部完成了Spring容器的加载(调用了refresh方法).


然后在tomcat的StandardWrapper#initServlet调用javax.servlet.Servlet#init
会循环加载多个Servlet,直到加载到DispatcherServlet之后会先调用DispatcherServlet的父类
HttpServletBean#init调用HttpServletBean#initServletBean(调用到FrameworkServlet#initServletBean)
调用FrameworkServlet#initWebApplicationContext(模版方法模式,初始化容器用的)

在initWebApplicationContext方法内

initWebApplicationContext调用
FrameworkServlet#configureAndRefreshWebApplicationContext经过一系列的处理,最终调用到ConfigurableApplicationContext#refresh 完成SpringMVC容器的初始化
initWebApplicationContext又调用了FrameworkServlet#onRefresh(子类DispatcherServlet的onRefresh执行),然后调用DispatcherServlet#initStrategies完成SpringMVC的九大组件初始化.(比如说视图解析器,多文件上传组件,模版处理器组件,handlerMapping组件初始化等等.)



1. 组件初始化

在DispatcherServlet#doService调用到DispatcherServlet#doDispatch,


DispatcherServlet#initStrategies

//初始化策略
protected void initStrategies(ApplicationContext context) {
//多文件上传的组件
initMultipartResolver(context);
//初始化本地语言环境
initLocaleResolver(context);
//初始化模板处理器
initThemeResolver(context);
//handlerMapping
initHandlerMappings(context);
//初始化参数适配器
initHandlerAdapters(context);
//初始化异常拦截器
initHandlerExceptionResolvers(context);
//初始化视图预处理器
initRequestToViewNameTranslator(context);
//初始化视图转换器
initViewResolvers(context);
//
initFlashMapManager(context);
}