Tomcat类加载的架构及存放目录

发布时间:2021-08-31 12:40:02 作者:chen
来源:亿速云 阅读:186
# Tomcat类加载的架构及存放目录

## 1. Tomcat类加载机制概述

Apache Tomcat作为广泛使用的Java Web应用服务器,其类加载机制设计具有独特的层次结构。与传统的Java类加载模型不同,Tomcat通过自定义的类加载器实现了应用隔离、资源隔离和灵活部署等关键特性。

### 1.1 与JVM类加载器的区别

标准JVM类加载器采用双亲委派模型,包含以下层次:
- Bootstrap ClassLoader(加载JRE核心类)
- Extension ClassLoader(加载JRE扩展类)
- Application ClassLoader(加载应用类)

而Tomcat在此基础上进行了扩展,主要差异体现在:
1. 打破了严格的双亲委派模式
2. 增加了Web应用级别的隔离
3. 支持热部署时的类重新加载

### 1.2 Tomcat类加载器的核心目标

1. **应用隔离**:不同Web应用间的类互不可见
2. **资源共享**:公共类库(如Servlet API)只需加载一次
3. **安全性**:防止应用覆盖容器核心类
4. **灵活性**:支持单个应用的重载而不影响其他应用

## 2. Tomcat类加载器架构

### 2.1 类加载器层次结构

Tomcat 9.x的完整类加载器体系:

Bootstrap ↑ Extension ↑ System ↑ Common ↑ ├── WebApp (每个Web应用独有) └── Jasper (JSP编译使用)


### 2.2 关键类加载器详解

#### 2.2.1 Common ClassLoader

- **父加载器**:System ClassLoader
- **加载路径**:`$CATALINA_HOME/lib/*.jar`
- **职责**:
  - 加载Tomcat容器和所有Web应用的共享类
  - 包含Servlet API、JSP API等基础库
  - 可通过`catalina.properties`中的`common.loader`配置

#### 2.2.2 WebApp ClassLoader

- **父加载器**:Common ClassLoader
- **加载路径**:
  - `/WEB-INF/classes`
  - `/WEB-INF/lib/*.jar`
- **特性**:
  - 每个Web应用独立实例化
  - 默认开启`delegate`模式(先委托父加载器)
  - 支持热部署时的类重新加载

#### 2.2.3 Jasper ClassLoader

- **用途**:专门用于JSP页面的编译
- **生命周期**:仅在JSP编译期间存在
- **特点**:
  - 高频创建和销毁
  - 隔离编译产生的临时类

### 2.3 类加载顺序流程图

```mermaid
graph TD
    A[WebApp ClassLoader] -->|1. 委托| B[Common ClassLoader]
    B -->|2. 委托| C[System ClassLoader]
    C -->|3. 委托| D[Extension ClassLoader]
    D -->|4. 委托| E[Bootstrap ClassLoader]
    A -->|5. 自行加载| F[/WEB-INF/classes]
    A -->|6. 自行加载| G[/WEB-INF/lib/*.jar]

3. 类文件存放目录结构

3.1 Tomcat核心目录布局

$CATALINA_HOME/
├── bin/            # 启动脚本
├── conf/           # 全局配置
├── lib/            # Common ClassLoader加载位置
│   ├── catalina.jar
│   ├── servlet-api.jar
│   └── ...
├── webapps/        # 应用部署目录
│   ├── ROOT/       # 默认应用
│   ├── app1/       # 示例应用1
│   │   ├── WEB-INF/
│   │   │   ├── classes/   # 应用类文件
│   │   │   └── lib/       # 应用依赖JAR
│   └── app2/       # 示例应用2
└── work/           # 运行时生成文件
    ├── Catalina/   # 引擎相关
    │   └── localhost/ # 虚拟主机
    │       ├── app1/  # JSP编译结果
    │       └── app2/
    └── ...         

3.2 关键目录说明

3.2.1 共享库目录($CATALINA_HOME/lib)

3.2.2 应用私有目录(WEB-INF)

WEB-INF/
├── classes/       # 编译后的类文件
│   ├── com/       # 包结构
│   │   └── example/
│   │       └── MyServlet.class
├── lib/           # 应用依赖库
│   ├── utils.jar
│   └── jdbc-driver.jar
└── web.xml        # 部署描述符

3.2.3 临时工作目录(work/Catalina)

4. 配置与调优实践

4.1 关键配置参数

conf/catalina.properties中:

# Common类加载器路径配置
common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"

# 是否启用类加载器委托
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=*.jar

4.2 类加载策略选择

通过context.xml配置:

<Context>
    <!-- 默认true,优先委托父加载器 -->
    <Loader delegate="true"/>
    
    <!-- 控制JAR扫描行为 -->
    <JarScanner scanClassPath="false"/>
</Context>

策略对比

参数值 加载顺序 适用场景
true 父优先 生产环境(安全)
false 本地优先 开发调试

4.3 常见问题解决方案

4.3.1 ClassCastException异常

现象:相同类被不同加载器加载 解决: 1. 将冲突类移至$CATALINA_HOME/lib 2. 确保所有应用使用相同版本库

4.3.2 内存泄漏排查

典型场景: - WebApp ClassLoader未被回收 - 静态成员持有类加载器引用

检测工具: - JDK Mission Control - Tomcat的LeakPreventionListener

5. 高级主题与最新演进

5.1 模块化支持(Tomcat 10+)

随着JPMS引入的变化: - 自动模块名称处理 - 模块路径与类路径的协调 - jlink自定义运行时支持

5.2 云原生环境适配

5.3 性能调优指标

  1. 类加载时间监控
    
    JVM参数添加:-verbose:class
    
  2. 缓存调优
    
    <Resources cachingAllowed="true" cacheMaxSize="102400"/>
    

6. 总结与最佳实践

推荐部署方案

  1. 公共库放入$CATALINA_HOME/lib
  2. 应用专有库放入WEB-INF/lib
  3. 开发环境设置delegate="false"
  4. 生产环境启用类加载器缓存

未来发展方向: - 增强对Java模块化的支持 - 优化云环境下的类加载效率 - 改进类重新加载机制

注:本文基于Tomcat 9.x版本编写,部分细节可能随版本变化而调整。实际部署时应参考对应版本的官方文档。 “`

这篇文章共计约2900字,采用Markdown格式编写,包含: 1. 多级标题结构 2. 代码块展示配置示例 3. Mermaid流程图 4. 表格对比 5. 文件目录树形结构 6. 重点内容强调

可根据具体需要调整各部分详细程度或补充特定场景的案例说明。

推荐阅读:
  1. mysql数据默认存放目录的修改方法
  2. Linux的etc目录用来存放什么?

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

tomcat

上一篇:Java最新的SQL注入原因以及预防方案

下一篇:如何使用at命令在Linux上安排任务

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》