双亲委派到底是个啥

简介: 双亲委派到底是个啥

很多人面试的时候或多或少都会遇到这个问题, Java双亲委派是啥?若是面试前没看面试宝典, 可能真的一时半会回答不上来。因为工作中压根就不会遇到或想这个问题。那我今天好好聊聊这个双亲委派机制。

其实看名思义,大概就能知道是个啥, 想想我们的祖传三辈的那个味。就是你的基因,是继承了上一辈的。 而你的父亲继承了你爷爷。 就一直往上找。 直至最顶层。 感觉像是金字塔,其实不然啊。扯远了,还是回到技术本身。

我们先想想,Java加载类的机制。是不是见过loadClass 这个方法。 里面的实现是啥。其实这个方法是在ClassLoader 类里面。

大概画个图,见图说话


图中我们大体就可以知道,双亲委派其实自己先不加载某个类,而是交由父类去加载,父类找不到了,才会自己去加载, 若是自己不可以加载,则会包类找不到的异常。

双亲委派的规定就是, 自己不先加载,而是交由父类去折腾加载,父类折腾加载不出来, 才会自己去折腾加载。这样做的目的是什么呢?

我觉的是这两点:

1、防止重复加载同一个class文件, 防重,不会出现一个模块下,都有一样的类。通过委托人去上面问问,看看是否有加载过了,就不用再加载一遍了,保证数据安全性。

2、保证某些核心的class文件不会篡改, 通过委托的方式, 对一些若是篡改的class文件,也不会去加载。不同的加载器加载同一个class,也不会是同一个class对象。保证了class执行安全。


那居然双亲委派有那么多好处,但我还是想打破它怎么办。

其实也挺简单, 就是自己去实现加载类的机制, loadClass 重写个loadClass方法,里面写自己的实现。那你知道有哪些是打破了双亲委派的。

这个我知道啊, tomcat的加载类就改了, 把双亲委派给打破了。

tomcat是怎么做的。tomcat webapp 下是放了我们不同的war ,但若是我们要部署两个war怎么办, 且两个war包的类有相同的。 若是通过双亲委派机制那样的做法是有问题, 会遇到加载的类不是想要的,冲突了。 tomcat为了做到让两个应用之间隔离,互不干扰, 就打破了双亲委派机制, 让自己加载自己的,不用去找什么父类的加载器去加载。


除了tomcat,其实我们先前写jdbc ,通过driver去加载不同厂商的数据库的驱动, 它是所谓的SPI 机制。这样他就不用通过统一的父类的加载器实现,而是通过自己的实现去加载,毕竟不同的厂商的实现驱动不一样的哈。若是交由父类加载器去实现的话,BootStrapClassLoader 会加载到不同厂商的驱动,这样是有问题的。显然是不可以的,Java代码中都没有调用它,你给我加载是啥意思,明显是坑我嘛!


DriverManager的解决方案是啥, 他是在初始化的时候, 搞了个上下文加载器。去获取Connection的时候,是使用 ‘线程上下文加载器’去加载Connection的,而这里的线程上下文加载器其实还是ApplicationClassLoader。

所以在获取Connection的时候,还是先找Extenstion ClassLoader和BootStrap ClassLoader, 只不过这两个加载器肯定是加载不到的,最终由Application ClassLoader 进行加载。其实这种情况, 有的人会认为 是破坏了双亲委派机制, 因为本来明明应该是由 BootStrap ClassLoader 进行加载的, 结果你来一手 “线程上下文加载器”,改掉了 ‘类加载器’。


有的人,觉得没有打破双亲委派机制, 只是改由, “线程上下文加载器”进行类加载了,但还是遵守了 :‘依次往上找父类加载器进行加载, 找不到时才由自身加载’。 认为“‘原则’”上是没有变的。


这都是 “智者见智仁者见仁”吧,各位看官自己判断掂量;。


扯了那么多。总结一下呗。


前置只是就是, JDK中默认的类加载器, 他有三个,分别是 AppClassLoader, Ext ClassLoader, BootStrap ClassLoader。AppClassLoader 的父加载器为 Ext ClassLoader , Ext ClassLoader 的父加载器为 BootStrap ClassLoader。这里的父子关系 并不是通过继承实现的。而是组合


什么是双亲委派机制: 加载器在加载过程中, 类交由父类加载器进行加载。父类加载器没有找到才由自身加载。


双亲委派机制目的:为了防止内存中存在多份同样的字节码(安全)

类加载规则:如果一个类由类加载器A加载,那么这个类的依赖类也是由「相同的类加载器」加载。

如何打破双亲委派机制:自定义ClassLoader,重写loadClass方法(只要不依次往上交给父加载器进行加载,就算是打破双亲委派机制)

打破双亲委派机制案例:Tomcat

  1. 为了Web应用程序类之间隔离,为每个应用程序创建WebAppClassLoader类加载器
  2. 为了Web应用程序类之间共享,把ShareClassLoader作为WebAppClassLoader的父类加载器,如果WebAppClassLoader加载器找不到,则尝试用ShareClassLoader进行加载
  3. 为了Tomcat本身与Web应用程序类隔离,用CatalinaClassLoader类加载器进行隔离,CatalinaClassLoader加载Tomcat本身的类
  4. 为了Tomcat与Web应用程序类共享,用CommonClassLoader作为CatalinaClassLoader和ShareClassLoader的父类加载器
  5. ShareClassLoader、CatalinaClassLoader、CommonClassLoader的目录可以在Tomcat的catalina.properties进行配置

线程上下文加载器:由于类加载的规则,很可能导致父加载器加载时依赖子加载器的类,导致无法加载成功(BootStrap ClassLoader无法加载第三方库的类),所以存在「线程上下文加载器」来进行加载。

目录
相关文章
|
2月前
|
Java 数据库连接
什么是双亲委派?如何打破双亲委派?
什么是双亲委派?如何打破双亲委派?
100 0
|
2月前
|
存储 Java 编译器
类加载机制和双亲委派机制
类加载机制和双亲委派机制
|
2月前
|
Java
双亲委派源码分析
双亲委派源码分析
19 0
|
2月前
|
Java
【JVM】双亲委派机制、打破双亲委派机制
【JVM】双亲委派机制、打破双亲委派机制
23 1
|
2月前
|
前端开发 Java API
JVM 类加载器 双亲委派机制
【1月更文挑战第3天】JVM 类加载器 双亲委派机制
|
9月前
双亲委派机制
双亲委派机制
|
12月前
|
前端开发 Java
05-说下类加载器和双亲委派机制
在明白了整个类从加载到初始化的过程,接下来我们有必要来说下类加载器的概念,因为实现上述过程是必须依靠加载器来实现的。
57 0
05-说下类加载器和双亲委派机制
|
缓存 Java API
双亲委派机制是什么?
如果跟同事谈“双亲委派”,难免显得很八股了,但是这个“双亲委派”却是JVM在类加载环节必不可少的一个操作,充分的理解它,能够使我们更加良好的理解JVM在加载类的时候背后细节。不仅如此,在学习了解一些其他的技术,例如:SPI、OSGI等等,也能相辅相成,融会贯通,可谓“两仪生四象,四象生八卦”
186 1
双亲委派机制是什么?
|
安全 Java 应用服务中间件
浅谈双亲委派机制
经典八股文之双亲委派模型
132 0
【双亲委派】
【双亲委派】