(一)注册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); } |
---|