双亲委派机制

本文详细介绍了Java的双亲委派机制,解释了其为何存在以及如何自定义类加载器。同时,重点讨论了Tomcat如何打破双亲委派,以实现应用的类隔离和资源优化。Tomcat的类加载器结构包括CommonLoader、CatalinaLoader、SharedLoader和WebappClassLoader,每种加载器有特定的职责,确保了类库的隔离和共享。
摘要由CSDN通过智能技术生成

类加载其实就是双亲委派机制,加载某个类的时候会先委托父类加载器寻找目标,找不到在委托到上层父类加载器,如果所有父类加载器都没有找到目标类,则在自己的类加载路径查找目标类。

双亲委派机制简单点说,先找父类加载,找不到再从子类加载。

源码中,调用loadClass方法的时候会先判断目标类是否已经加载过了,如果加载过就无需重复加载,直接返回,如果没有,去判断parent不为空,调用parent.loadClass方法,如果parent为空,则调用findBootstrapClassOrNull方法,有引导类去加载;如果都没有找到目标类,则有调用当前类加载器去加载,调用findClass方法查找并加载

为什么要有双亲委派机制

1、沙箱安全机制:防止核心类被随意篡改,比如Sring类,如果自己写的String类被加载,则就会引起很大问题。

2、避免类重复加载:当父类已经加载该类,子类不需要重复加载,保证只加载一次。

如何自定义加载器

继承java.lang.ClassLoader类,重写loadClass方法,该类实现双亲委派机制,还有一个findClass方法,默认为空,重写findClass方法。

如何打破双亲委派机制

自定义类加载器的时候,重写loadClass方法,不实现双亲委派机制,就是不去先去父类找目标类,直接从当前类加载器去加载就行了。

Tomcat打破双亲委派机制

 1. 一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的 不同版本,不能要求同一个类库在同一个服务器只有一份,因此要保证每个应用程序的类库都是 独立的,保证相互隔离。

  如果使用默认的类加载器机制,那么是无法加载两个相同类库的不同版本的,默认 的类加器是不管你是什么版本的,只在乎你的全限定类名,并且只有一份。

2、部署在同一个web容器中相同的类库相同的版本可以共享。否则,如果服务器有10个应用程 序,那么要有10份相同的类库加载进虚拟机。

  默认的类加载器是能够实现的,因为他的职责就是保证唯一性。

  tomcat的几个主要类加载器: commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容 器本身以及各个Webapp访问;

  catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不 可见; sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有 Webapp可见,但是对于Tomcat容器不可见;

 WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前 Webapp可见,比如加载war包里相关的类,每个war包应用都有自己的

 WebappClassLoader,实现相互隔离,比如不同war包应用引入了不同的spring版本, 这样实现就能加载各自的spring版本;

  从图中的委派关系中可以看出: CommonClassLoader能加载的类都可以被CatalinaClassLoader和SharedClassLoader使用, 从而实现了公有类库的共用,而CatalinaClassLoader和SharedClassLoader自己能加载的类则 与对方相互隔离。

  WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader 实例之间相互隔离。 而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的 就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例, 并通过再建立一个新的Jsp类加载器来实现JSP文件的热加载功能。

  tomcat 这种类加载机制违背了java 推荐的双亲委派模型了吗?答案是:违背了。 很显然,tomcat 不是这样实现,tomcat 为了实现隔离性,没有遵守这个约定,每个 webappClassLoader加载自己的目录下的class文件,不会传递给父类加载器,打破了双亲委 派机制。

注意:同一个JVM内,两个相同包名和类名的类对象可以共存,因为他们的类加载器可以不一 样,所以看两个类对象是否是同一个,除了看类的包名和类名是否都相同之外,还需要他们的类 加载器也是同一个才能认为他们是同一个。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值