Tomcat中为什么要使用自定义类加载器

news/2024/9/25 1:18:00

Tomcat 使用自定义类加载器主要是基于以下几个关键原因:

1.应用隔离:Tomcat作为一个Web容器,能够同时部署和运行多个Web应用程序。每个应用可能依赖不同的库版本或者包含同名类,为了确保每个应用的类库相互独立,避免类冲突,Tomcat 为每个Web应用提供了一个独立的类加载器实例,即`WebAppClassLoader`。这样,即使不同应用中存在相同的类名,它们也是被各自的应用类加载器加载,互不影响。

2.热部署与热替换:自定义类加载器支持热部署和类的热替换功能。当Web应用发生变化时,不需要重启整个Tomcat服务器,只需重新加载对应的Web应用即可。通过创建新的类加载器来加载更新后的类,旧的类加载器和旧的类可以被垃圾回收,实现类的平滑升级。

3.遵循Servlet规范:Servlet规范要求Web容器必须为每个Web应用提供独立的类加载器上下文,以满足应用的独立性和安全性需求。Tomcat的自定义类加载器体系结构正是对这一规范的实现。

4. 层次化加载机制:Tomcat的类加载器体系采用分层设计,包括但不限于以下几个关键的类加载器:


   - Bootstrap ClassLoader:负责加载JDK核心类库。
   - Common/Shared ClassLoader:加载Tomcat和所有Web应用共享的类库。
   - Catalina ClassLoader:加载Tomcat自身的类。
   - WebApp ClassLoader:为每个Web应用创建,负责加载该应用特有的类和库。
   

// 自定义类加载器的基类,模仿Tomcat中类加载器的委托逻辑
abstract class CustomClassLoader extends ClassLoader {protected ClassLoader parent; // 父加载器引用

protected CustomClassLoader(ClassLoader parent) {super(parent);this.parent = parent;}@Overrideprotected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);if (c == null) {try {// Delegate to the parent class loader if not found
c = super.loadClass(name, false); // 正确的调用方式
} catch (ClassNotFoundException e) {// If still not found, then invoke findClass in this class loader
c = findClass(name);}}if (resolve) {resolveClass(c);}return c;}}// 抽象方法,子类需实现以定义如何查找类
protected abstract Class<?> findClass(String name) throws ClassNotFoundException;
}
// 模拟TomcatCommonClassLoader
class CommonClassLoader extends CustomClassLoader {public CommonClassLoader(ClassLoader parent) {super(parent);}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {System.out.println("CommonClassLoader wei");// 实现查找共享类的逻辑
throw new ClassNotFoundException("Not implemented wei");}
}
// 自定义类加载器的基类,模仿Tomcat中类加载器的委托逻辑
abstract class CustomClassLoader extends ClassLoader {protected ClassLoader parent; // 父加载器引用

protected CustomClassLoader(ClassLoader parent) {super(parent);this.parent = parent;}@Overrideprotected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);if (c == null) {try {// Delegate to the parent class loader if not found
c = super.loadClass(name, false); // 正确的调用方式
} catch (ClassNotFoundException e) {// If still not found, then invoke findClass in this class loader
c = findClass(name);}}if (resolve) {resolveClass(c);}return c;}}// 抽象方法,子类需实现以定义如何查找类
protected abstract Class<?> findClass(String name) throws ClassNotFoundException;
}

上面三段代码分别是:一个基础的,模拟Tomcat中通用的加载逻辑;一个,代表Tomcat中用于加载共享类库的类加载器;以及一个,模拟每个Web应用独有的类加载器。在方法中,我们展示了如何通过Web应用类加载器加载类,同时这个加载器会委托给共享类加载器,模拟了Tomcat类加载的委托机制。

这种层次结构允许类加载器首先在本地查找类,找不到时再委托给父加载器,既保证了类加载的高效性,又确保了类的正确加载顺序,避免了类覆盖问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/30879.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

OSCP靶机训练Kitoptrix Level 3

Vulnhub——KioptrixVM3 前期准备:kali攻击机:10.0.0.4 靶机:10.0.0.12 将两台机器都设置为NAT模式渗透过程: 第一步:存活主机探测 arp-scan -l第二步:端口扫描 nmap --min-rate 10000 -p- 10.0.0.12第三步:基本信息扫描 nmap -sT -sC -sV -O -p22,80 10.0.0.12第四步:…

OSCP靶机训练Kioptrix Level 4

Vulnhub——Kioptrix Level 4 前期准备:kali攻击机:10.10.10.12 靶机:10.10.10.15 将两台机器都设置为NAT模式渗透过程 1、首先是存活主机探测,确认目标是否在线 arp-scan -l2、然后对目标进行端口扫描, 确认目标开放了哪些端口以及服务3、开放了4个端口,首先目光集中在…

OSCP靶机训练Kioptrix Level 1

Vulnhub——Kioptrix Level 1 前期准备: ​ 1、kali攻击机:10.0.0.4 NAT模式 ​ 2、靶机:10.0.0.10 NAT模式 ​ 注意: ​ 该靶机默认为桥接模式,且在虚拟机中修改为NAT模式,在靶机启动之后又自动更改为了桥接模式 ​ 需要在靶机的配置文件中进行修改 ​ 将所有Bridg…

vcenter创建数据中心加入ESXI主机

vcenter创建数据中心加入ESXI主机右键选择vcenter主机,点新建数据中心 2、点确定 3、对Datacenter右键,然后选择添加主机 4、添加主机IP地址 5、添加用户密码,然后下一页 6、点是 7、会显示摘要,按下一页 8、分配许可证 9、按是 10、按下一页 11、虚拟机位置,不用…

SQL Server实战七:自定义数据类型、标量值、内嵌表值、多语句表值函数的操作

本文介绍基于Microsoft SQL Server软件,实现数据库用户自定义数据类型的创建、使用与删除,以及标量值、内嵌表值、多语句表值函数等用户定义函数的创建、使用、删除方法~本文介绍基于Microsoft SQL Server软件,实现数据库用户自定义数据类型的创建、使用与删除,以及标量值、…

Layui的进度条使用

我用的是 第二种上代码 首先引入 layui的css和js html部分<div class="layui-progress" lay-showpercent="true" style="margin-top:10px" lay-filter="demo-filter-progress"><div class="layui-progress-bar" l…

sh 不是内部或外部命令,也不是可运行的程序 或批处理文件。

我们在windows系统中执行:sh nacos-config.sh -h 127.0.0.1命令是报错的。 报错:sh 不是内部或外部命令,也不是可运行的程序 或批处理文件。 但是作为一名软件开发人员,我们的电脑上一般都是安装有git的。 这个时候,我们可以使用git执行上面的命令就可以了,因为git是安装…

FatFs --- 短文件名 / 长文件名

FATFS 默认使用的文件名格式是8.3短文件名格式,即文件名8个字节,扩展名3个字节 需要定义以下宏来支持长文件名