# Tomcat 源码构建及核心流程剖析


<!--more-->


## 一、源码构建

仅做简单思路介绍，读源码的方式很多种...

- 下载源码

  下载xxx-xxx-xxx-src的源码包

- 解压后在目录下创建pox.xml文件，内容如下

  ```xml
  <?xml version="1.0" encoding="UTF-8"?>
  <project xmlns="http://maven.apache.org/POM/4.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
  
      <groupId>org.apache.tomcat</groupId>
      <artifactId>apache-tomcat-8.5.50-src</artifactId>
      <name>Tomcat8.5</name>
      <version>8.5</version>
  
      <dependencies>
          <dependency>
              <groupId>org.easymock</groupId>
              <artifactId>easymock</artifactId>
              <version>3.4</version>
          </dependency>
          <dependency>
              <groupId>ant</groupId>
              <artifactId>ant</artifactId>
              <version>1.7.0</version>
          </dependency>
          <dependency>
              <groupId>wsdl4j</groupId>
              <artifactId>wsdl4j</artifactId>
              <version>1.6.2</version>
          </dependency>
          <dependency>
              <groupId>javax.xml</groupId>
              <artifactId>jaxrpc</artifactId>
              <version>1.1</version>
          </dependency>
          <dependency>
              <groupId>org.eclipse.jdt.core.compiler</groupId>
              <artifactId>ecj</artifactId>
              <version>4.5.1</version>
          </dependency>
          <dependency>
              <groupId>javax.xml.soap</groupId>
              <artifactId>javax.xml.soap-api</artifactId>
              <version>1.4.0</version>
          </dependency>
      </dependencies>
  
      <build>
          <!--指定源⽬录-->
          <finalName>Tomcat8.5</finalName>
          <sourceDirectory>java</sourceDirectory>
          <resources>
              <resource>
                  <directory>java</directory>
              </resource>
          </resources>
          <plugins>
              <!--引⼊编译插件-->
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-compiler-plugin</artifactId>
                  <version>3.1</version>
                  <configuration>
                      <encoding>UTF-8</encoding>
                      <source>11</source>
                      <target>11</target>
                  </configuration>
              </plugin>
          </plugins>
      </build>
  </project>
  ```

- 在 apache-tomcat-8.5.50-src ⽬录中创建 source ⽂件夹

- 将 conf、webapps ⽬录移动到刚刚创建的 source ⽂件夹中

- 将源码⼯程导⼊到 IDEA 中

- 给 tomcat 的源码程序启动类 Bootstrap 配置 VM 参数，因为 tomcat 源码运⾏也需要加载配置⽂件等。

  ```properties
  -Dcatalina.home=/Users/***/a-studing/source-code/apache-tomcat-8.5.50-src/source
  -Dcatalina.base=/Users/***/a-studing/source-code/apache-tomcat-8.5.50-src/source
  -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
  # 此为conf 目录下logging.properties文件绝对路径
  -Djava.util.logging.configfile=/Users/***/a-studing/source-code/apache-tomcat-8.5.50-src/source/conf/logging.properties 
  ```

- 运⾏ Bootstrap 类的 main 函数，此时就启动了tomcat，启动时候会去加载所配置的 conf ⽬录下的server.xml等配置⽂件，所以访问8080端⼝即可，但此时我们会遇到如下的⼀个错误

  原因是Jsp引擎Jasper没有被初始化，从⽽⽆法编译JSP，我们需要在tomcat的源码ContextConfig类中的configureStart⽅法中增加⼀⾏代码将 Jsp 引擎初始化

  > 如果出现以下错误：
  >
  > 程序包 sun.rmi.registry 已在模块 java.rmi 中声明, 但该模块未将它导出到未命名模块
  >
  > 按照idea的提示修复即可

- 启动完成后，访问localhost:8080即可成功

## 二、核心流程剖析

Tomcat中的各容器组件都会涉及创建、销毁等，因此设计了⽣命周期接⼝Lifecycle进⾏统⼀规范，各容器组件实现该接⼝。

![img_9](https://img.zhaojq.top/20260727091812064.png "img_9")

- 启动流程

  ![img_10](https://img.zhaojq.top/20260727091812334.png "img_10")

- 请求处理流程

  ![img_11](https://img.zhaojq.top/20260727091812597.png "img_11")

  ![img_12](https://img.zhaojq.top/20260727091812860.png "img_12")










