Tomcat 8 Code Study

本来是打算从Tomcat7开始阅读源码的,可是奈何小编使用的是MacOS,Tomcat7依赖dbpc1.4版本,必须用JDK1.6编译,太过繁琐,遂着手Tomcat8…

Environment

  • MacOS
  • JDK7
  • Ant 1.8.x+

Download

1
$ wget https://github.com/apache/tomcat/archive/TOMCAT_8_0_0.tar.gz

目录结构

  • java
    源码目录
  • conf
    配置目录
  • build.xml
    ant构建文件
  • output
    默认编译输出目录

Build

Tomcat是使用Ant工具来构建的,在BUILDING.txt中有详细说明
执行以下两步就可以deploy一个tomcat容器

1
2
$ cd {tomcat.source}
$ ant

NOTE

  1. Tomcat默认是使用build.properties.default里的属性来进行构建的,推荐在源路径新建build.properties来构建自己的Tomcat,
    若遇到Ant工具报错时,第一种可能性就是base.path没有设置正确,这个路径是用来下载Tomcat依赖环境的,Tomcat默认是/usr/share/java,/usr/*是需要root权限的,这里你设定一个方便操作的路径即可。
  2. the archive file.tar.gz doesn’t exist,主要是dbcp2-2.0SNAPSHOT目标依赖文件不存在,到build.properties目录下查找官网地址,发现该版本已经不存在了,替换使用dbcp2-2.0.2-SNAPSHOT版本

Startup

  • 数据统计
    对Tomcat8做了个简单的数据统计,以*.java为结尾的文件,统计所有的’\n’字符。在根路径下统计,共计494831。在源代码路径下统计,共计362858。可以看出来,Tomcat的代码量还是相当庞大的>_<
  • 启动入口类
    1
    org.apache.catalina.startup.Bootstrap

我们简单的看一下类Doc:

Bootstrap loader for Catalina. This application constructs a class loader
for use in loading the Catalina internal classes (by accumulating all of the
JAR files found in the “server” directory under “catalina.home”), and
starts the regular execution of the container. The purpose of this
roundabout approach is to keep the Catalina internal classes (and any
other classes they depend on, such as an XML parser) out of the system
class path and therefore not visible to application level classes.

结合源码,可以看到,Bootstrap主要做两件事情,一个是初始化了Catalina(Tomcat)容器核心class以及依赖库的ClassLoader,此ClassLoader是应用级的ClassLoader,所以Tomcat自身的class以及依赖的任何第三方库都是对用户应用屏蔽的;另外就是启动Catalina(Tomcat)容器的初始化启动逻辑。

屏蔽原理:
1. 基于JVM加载类的双亲委托机制 实现自定义ClassLoader
2. 关键函数 Thread.currentThread().setContextClassLoader

Catalina主要有3个ClassLoader (URLClassLoader):
在catalina.properties定义

  • commonLoader
    common.loader,负责加载${catalina.home}/lib以及${catalina.base}/lib下的jar包
  • catalinaLoader
    server.loader,自定义loader,默认是commonLoader
  • sharedLoader
    shared.loader,自定义loader,默认是commonLoader

主程序入口类

1
org.apache.catalina.startup.Catalina

启动的两个关键方法

  • load(String args[]);
    1. 命令行解析
    2. 初始化Server实例
  • start();
坚持原创技术分享,您的支持将鼓励我继续创作!