【Tomcat源码级别掌握】
Tomcat源码级别掌握
- 1.Tomcat基础
- 1.1 web概念
- 2.Tomcat架构
- 2.1 连接器
- 2.2 容器 -- catalina
- 2.3 tomcat启动流程
- 3.Jasper
- 4.Tomcat服务器配置
- 5.Web应用配置
- 6.Tomcat管理配置
- 7.JVM配置
- 8.Tomcat集群
- 9.Tomcat 安全
- 10.Tomcat性能优化
- 11.Tomca附件功能
- 12. Tomcat源码下载
- 12.1 源码学习下载
- 12.2 导入Intellij IDEA,在源码根目录下创建pom.xml
- 12.3 配置源码中的jsp解析器(ContextConfig#configureStart)
- 12.4 解决控制条输出是乱码问题
1.Tomcat基础
1.1 web概念
软件架构:
- c/s:客户端/服务端 —> QQ、360
- B/S: 浏览器/服务端 —> 京东、网易、淘宝、、、
资源分类:
- 静态资源:所有用户访问结果都是一样的,称为静态资源。如css、html、js、jpg
- 动态资源:每个用户访问相同的资源,得到的结果可能不一样。如servlet、jsp,php,asp…
2.Tomcat架构
2.1 连接器

- EndPoint: Coyote通信端点,即通信监听的接口,是具体Socket接收和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议的。
- Tomcat中并没有EndPoint接口,而是提供了一个抽象类AbstractEndPoint,里面定义了两个内部类:Acceptor和SocketProcessor。Acceptor用于监听Socket连接请求。SocketProcessor用于处理接收到的Socket请求,它实现了Runnable接口,在Run方法里面调用协议处理组件Processor进行处理。为了提高处理能力,SocketProcessor被提交到线程池中俩执行。而这个线程池叫做执行器Excutor。
- processor: coyote协议处理接口,如果说EndPoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,Processor接收来自EndPoint的socket,读取字节流解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象。
2.2 容器 – catalina
- Tomcat是一个由一系列可配置的组件构成的web容器,而Catalina是Tomcat的servlet容器。
- Catalina是Servlet容器实现,包含了之前讲到的所有的容器组件,以及后续章节涉及到的安全、会话、集群、管理等Servlet容器架构的各个方面。
- 它通过松耦合的方式集成Coyote,以完成按照请求协议进行数据读写。同时,它还包括我们的启动入口、shell程序等。


各个组件的含义:
| 容器 | 描述 |
|---|---|
| Engine | 表示整个Catalina的servlet引擎,用来管理多个虚拟站点,一个service最多只能有一个Engine,但是一个引擎可包含多个host |
| Host | 代表一个虚拟主机,或者说一个站点,可以给tomcat配置多个虚拟主机地址,而一个虚拟主机下可以包含多个Context |
| Context | 表示一个web应用程序,一个web应用可以包含多个Wrapper |
| Wrapper | 表示一个Servlet,Wrapper作为容器中的最底层,不能包含子容器 |
2.3 tomcat启动流程

3.Jasper
4.Tomcat服务器配置
5.Web应用配置
6.Tomcat管理配置
7.JVM配置
8.Tomcat集群
9.Tomcat 安全
10.Tomcat性能优化
11.Tomca附件功能
12. Tomcat源码下载
12.1 源码学习下载
Tomcat源码地址下载: https://tomcat.apache.org/download-80.cgi#8.5.98
12.2 导入Intellij IDEA,在源码根目录下创建pom.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.98-src</artifactId><name>Tomcat8.5</name><version>8.5</version><build><finalName>Tomcat8.5</finalName><sourceDirectory>java</sourceDirectory><!-- <testSourceDirectory>test</testSourceDirectory> --><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>2.3</version><configuration><encoding>UTF-8</encoding><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><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></dependencies>
</project>
12.3 配置源码中的jsp解析器(ContextConfig#configureStart)
protected synchronized void configureStart() {// Called from StandardContext.start()if (log.isDebugEnabled()) {log.debug(sm.getString("contextConfig.start"));}if (log.isDebugEnabled()) {log.debug(sm.getString("contextConfig.xmlSettings",context.getName(),Boolean.valueOf(context.getXmlValidation()),Boolean.valueOf(context.getXmlNamespaceAware())));}webConfig();//初始化,引入下面一行代码context.addServletContainerInitializer(new JasperInitializer(), null);if (!context.getIgnoreAnnotations()) {applicationAnnotationsConfig();}if (ok) {validateSecurityRoles();}。。。。
}
12.4 解决控制条输出是乱码问题
/*1. org.apache.tomcat.util.res.StringManager类中的getString(final String key,final Object... args)方法*/
public String getString(final String key, final Object... args) {String value = getString(key);if (value == null) {value = key;}//try {value = new String(value.getBytes("ISO-8859-1"),"UTF-8");} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}MessageFormat mf = new MessageFormat(value);mf.setLocale(locale);return mf.format(args, new StringBuffer(), null).toString();}
/*2. org.apache.jasper.compiler.Localizer类的getMessage(String errCode)方法
*/
public static String getMessage(String errCode) {String errMsg = errCode;try {if (bundle != null) {errMsg = bundle.getString(errCode);}} catch (MissingResourceException e) {}try {errMsg = new String(errMsg.getBytes("ISO-8859-1"),"UTF-8");} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}return errMsg;}