上一篇分享是源码环境搭建和启动参数的配置 juejin.cn/post/690045…
在开始之前,还是要大致学习一下官方文档 tomcat.apache.org/tomcat-8.5-…
这三个目录可以让我们对tomcat有一个入门了解。
调试前准备:
使用Spring新建一个web工程my-springmvc-test,结构如下, 打成war包后部署到tomcat中
- 1. org.apache.catalina.core.StandardContext
一个StandardContext就代表了一个独立的web应用,对应webapps下的一个目录(war文件解压后形成的目录);
一个StandardContext有独立的类加载器ParallelWebappClassLoader
- 2. 处理过程
2.1 入口
图一 入口org.apache.catalina.startup.HostConfig.deployWARs
图二 每个war包单独一个DeployWar线程处理
将 HostConfig传递到 每个war的上下文中,作为tomcat与每个web应用的通信桥梁。
2.2 DeployWar执行入口
图三 DeployWar执行入口
2.3 为当前web应用生成一个StandardContext代表当前web应用,并转交到StandardHost
图四 生成一个StandardContext,并转交到StandardHost
2.4 StandardHost 记录StandardContext,并开始初始化StandardContext
图五 StandardHost 记录StandardContext,并启动StandardContext
2.5 解压war包
图六 解压war包
2.6 为当前应用创建类加载器
图七 为当前应用创建类加载器
2.7 记录类加载器需要加载的资源
图八 记录类加载器需要加载的资源
2.8 为当前的web application设置类加载器
图九 为当前的web application设置类加载器
图十 tomcat类加载器层级结构
至此,就完成了为当前线程()设置类加载器,也就是web application的类加载器。
2.9 configureStart
2.9.1 webConfig
图11 webConfig
webConfig 方法中包含的功能之一:扫描web应用中的 实现javax.servlet.ServletContainerInitializer(servlet 3.0开始才有)接口的类,但是这里没有调用其onStartup方法
3.0 执行onStartup
图12执行onStartup
2.9.1中扫描到的实现了javax.servlet.ServletContainerInitializer的类,在图12的位置会得到执行 (因为我们的war包中实现了javax.servlet.ServletContainerInitializer的四个类都是抽象类,根据 SpringServletContainerInitializer .onStartup方法可知,这四个类不会被执行)
图13 SpringServletContainerInitializer
(SpringServletContainerInitializer 是通过 java SPI机制发现的)
3.1 loadOnStartup中调用DispatcherServlet
图14 loadOnStartup
图15 调用DispatcherServlet.init开始初始化Spring上下文
至此,就与应用对接上了,即与 SpringMVC源码对接上了。