要了解 Tomcat 的工作原理,首先要知道 servlet 是怎么回事,Tomcat 遵守 servlet 标准。
1. Servlet
Servlet 是无状态的,所以一定是线程安全的。
Servlet
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
init
,service
和 destroy
方法是 servlet 的生命周期方法,由 servlet 容器
调用。init
方法会在 servlet 被初始化之后调用;service
方法在 servlet 的请求到来时调用;destroy
方法在 servlet 被移除之前调用。
ServletRequest \ ServletResponse
servlet 的 service
方法接受一个 ServletRequest
类型的参数和一个 ServletResponse
类型的参数,说明 servlet 容器会为每个请求创建一个ServletRequest
对象和一个 ServletResponse
对象。ServletRequest
代表传递给 servlet 的请求; ServletResponse
代表响应。
请求到达 servlet 容器时,servlet 容器要去加载对应的 servlet 处理请求,所以要知道类加载器的原理。
2. WAR 文件组织结构
类加载器要知道去哪里加载类文件,所以先介绍一下应用部署时的文件组织结构。
WAR 文件的根目录组织如下:
- *.html, *.jsp, etc:对客户端可见的 HTML 等文件。
- /WEB-INF/web.xml:应用的 Web Application Deployment Descriptor。这个文件描述了组成该应用的 servlet 和其他组件、启动参数和容器管理的安全策略等(参考默认的 web.xml)。
- /WEB-INF/classes/:包含不是以 JAR 形式打包的 class 文件,通常是 servlet 的 class 文件。
- /WEB-INF/lib/:包含所有应用必须的 JAR 文件。
此外还有 Tomcat 的上下文描述文件(Tomcat Context Descriptor):/META-INF/context.xml。
3. ClassLoader
Java 的类加载原理参考深入探讨 Java 类加载器。
web 应用的类加载模式和 Java 的类加载代理模式有所不同:
When a request to load a class from the web application’s WebappX class loader is processed, this class loader will look in the local repositories first, instead of delegating before looking.
Tomcat 有四种类加载器:
- Bootstrap:加载 JVM 运行时类型和扩展类型(
$JAVA_HOME/jre/lib/ext
)。 - System:加载以下目录的类型:
- $CATALINA_HOME/bin/bootstrap.jar
- $CATALINA_BASE/bin/tomcat-juli.jar or $CATALINA_HOME/bin/tomcat-juli.jar
- $CATALINA_HOME/bin/commons-daemon.jar
- Common:加载对所有对 web 应用和 Tomcat 内部类型可见的类型。
- WebappX:每个 web 应用独有的,加载
/WEB-INF/classes
和/WEB-INF/lib
下的类型。
Bootstrap
|
System
|
Common
/ \
Webapp1 Webapp2 ...
一个 web 应用的类加载顺序如下:
- Bootstrap classes of your JVM
- /WEB-INF/classes of your web application
- /WEB-INF/lib/*.jar of your web application
- System class loader classes (described above)
- Common class loader classes (described above)
如果设置<Loader delegate="true"/>
,则加载顺序如下:
- Bootstrap classes of your JVM
- System class loader classes (described above)
- Common class loader classes (described above)
- /WEB-INF/classes of your web application
- /WEB-INF/lib/*.jar of your web application