Tomcat 通过为每个 Web 应用创建独立的 WebAppClassLoader 实现类加载隔离,确保同名类在不同应用中互不干扰;其本地优先加载策略打破双亲委派,支持版本隔离;通用类由 Common/SharedClassLoader 统一供给;并通过线程上下文类加载器使框架能访问应用类。

Tomcat 的类加载器隔离机制,本质是用“多个加载器实例”代替“一个加载器全局管理”,让每个 Web 应用拥有独立的类加载空间。同一个类名(如 com.example.User),被不同 WebAppClassLoader 加载后,在 JVM 中就是两个完全无关的 Class 对象——静态变量不共享、类型强转会抛 ClassCastException、卸载应用时相关类可一并回收。
每个应用独享 WebAppClassLoader
Tomcat 启动时,为每个部署的应用(如 /app1、/app2)创建独立的 WebAppClassLoader 实例。JVM 判定类是否相同,必须同时满足:全限定名一致 + 加载器实例相同。因此:
-
app1/WEB-INF/classes/com/example/User.class→ 由 App1 的加载器生成 Class A -
app2/WEB-INF/classes/com/example/User.class→ 由 App2 的加载器生成 Class B - Class A 和 Class B 在 JVM 内存中互不可见,哪怕字节码一模一样
本地优先加载,打破双亲委派
WebAppClassLoader 重写了 loadClass(),不再严格遵循“先父后己”,而是:
- 先查自己已加载的类缓存(
findLoadedClass) - 再从
WEB-INF/classes扫描 .class 文件 - 再遍历
WEB-INF/lib/中所有 JAR 包 - 仅当以上全部失败,才委托给父加载器(Shared → Common → System)
这种策略让 app1 可用 slf4j-api-1.7.30.jar,app2 可用 slf4j-api-2.0.9.jar,版本互不干扰。
立即学习“Java免费学习笔记(深入)”;
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
分层复用共享类,避免重复加载
不是所有类都要隔离。像 javax.servlet.Servlet、org.springframework.context.ApplicationContext 这类通用依赖,通过父加载器统一供给:
-
CommonClassLoader:加载
$CATALINA_HOME/lib/,供 Tomcat 内核与所有应用共享(如 Servlet API) -
SharedClassLoader(可选):加载
$CATALINA_HOME/shared/lib/,供多个应用共用工具包 - WebAppClassLoader 在本地找不到时才向上委托,确保 Spring 等只加载一次
线程上下文类加载器保障框架调用
Spring、JDBC 驱动等容器级框架由 CatalinaClassLoader 加载,本身看不到 Web 应用里的类。Tomcat 在处理请求时会动态设置:
Thread.currentThread().setContextClassLoader(webAppClassLoader)
这样 Spring 就能通过上下文加载器正确加载用户编写的 Controller、Service 类,实现框架与业务代码的协同。

















