一. 问什么要学习tomcat
tomcat是目前非常流行的web容器,其性能和稳定性也是非常出色的,学习其框架设计和底层的实现,不管是使用、性能调优,还是应用框架设计方面,肯定会有很大的帮助
二. 运行源码
1.下载源码
Tomcat各版本源码:https://archive.apache.org/dist/tomcat/
Tomcat安装包:https://tomcat.apache.org/
为什么又要下载源码,又要下载安装包?
源码中webapps是没有编译的,需要用安装包里的替换,并且Tomcat用的是ant+build.xml依赖管理,这种方式比较老,现在都用maven、gradle了,所以可以手动换成maven,但是有些包在maven仓库中找不到,可以从Tomcat安装包lib目录下获取。
2. 导入源码
- 导入下载好的apache-tomcat-9.0.54-src,并导入IDEA,然后在根目录下新建lib目录,让后将tomcat安装包中的jasper.jar复制过来
- 在根目录中添加pom.xml文件,并maven一下
- 在org.apache.jasper.compiler中报错的内容注释掉
<?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>tomcat9</artifactId> <name>tomcat9</name> <version>9.0</version> <build> <finalName>tomcat9</finalName> <sourceDirectory>java</sourceDirectory> <!--<testSourceDirectory>test</testSourceDirectory> test 下的有些文件报错,因此将test文件夹去掉了--> <resources> <resource> <directory>java</directory> </resource> </resources> <testResources> <testResource> <directory>test</directory> </testResource> </testResources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.0</version> <configuration> <encoding>UTF-8</encoding> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.0.2</version> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.9.5</version> </dependency> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant-apache-log4j</artifactId> <version>1.9.5</version> </dependency> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant-commons-logging</artifactId> <version>1.9.5</version> </dependency> <dependency> <groupId>javax.xml.rpc</groupId> <artifactId>javax.xml.rpc-api</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>org.eclipse.jdt.core.compiler</groupId> <artifactId>ecj</artifactId> <version>4.6.1</version> </dependency> <dependency> <groupId>biz.aQute.bnd</groupId> <artifactId>biz.aQute.bndlib</artifactId> <version>5.2.0</version> <scope>provided</scope> </dependency> </dependencies> </project>
- 此时启动tomcat时,会有乱码,处理方式是
三、总结:如何阅读源码
搭建源码阅读环境必不可少,一定要做到手里有书,眼里有源码,心里有debug。
书,具有引导和总结作用,Tomcat源码那么多,那么复杂,不知道从哪里开始读。可以先跟着书的目录,按章学习,从整体到细节,从外到内,从简到繁,快速建立起一个Tomcat基础架构网络:
Tomcat是一个HTTP服务器和Servlet容器,有两个核心组件:连接器和容器,链接器实现HTTP功能,容器实现装载Servlet的功能。
一个Server可以包含多个Service,一个Service包含多个Conector和一个Engine,一个Engine包含多个Host,一个Host包含多个Context,一个Context包含多个Wrapper,这些容器名称和层次关系是不是有些晕?一个Context就是一个熟悉的web服务,Wrapper可以理解为对Servlet的包装。
请求的响应从连接器–>容器–>连接器。连接器负责对外交流,接收请求做一些封装,然后交由容器处理,容器处理完后再返回给连接器做响应。
连接器、容器,从哪个开始学习呢?连接器涉及网络编程,HTTP协议等;容器里有类加载、各种设计模式,职责链、观察者(事件监听)模式用的最多,容易理解吸收。如果对网络编程(NIO、net、HTTP)不是很熟悉的,可以先从容器学起,如果对RPC框架Netty等熟悉的,那连接器就简单了。
带着任务和问题研究Tomcat源码。把整个Tomcat源码学习的艰巨工程划分为多个小任务,带着疑问去研究学习。比如可以先从日常熟悉的server.xml配置开始,搞懂里面的配置,为什么这么配置,这个路径为什么这样;带着问题就是Tomcat如何做热加载?如何部署加载一个web项目?如何处理一个请求?Tomcat生命周期是怎么实现的,如何做到一键启停?Tomcat为什么要自定义类加载器,如何打破双亲委派?等等。带着任务和问题,及时正向反馈,才能坚持把Tomcat这块硬骨头啃下来。
学习Tomcat源码也有一段时间了,中间半途而废多次,摸摸索索总结出一套适合自己的学习方式,真的,万事开头难,好的开头,成功一半,好的方法,事半功倍。后面会把我学习Tomcat源码的心得、过程持续分享出来,希望对你有用。