【JAVA开发】浅析双亲委派机制
双亲委派机制存在的意义
双亲委派只是一种说法,个人觉得叫单亲委派更合适,因为向上传递的父类只有一个,估计只是翻译过来的,形成的一种习惯,大家可以当做单亲委派
四种加载器都是用于类的加载,只是加载的对象不一样
bootstrap ClassLoader -负责核心JRE的类库加载,如rt.jar, charsets.jar等
Extension ClassLoader -负责加载拓展目录ext中的jar类包
Application ClassLoader -负责加载ClassPath路径下的类包
User ClassLoader -负责加载用户自定义路径下的类包
- 向上传递
向上传递啥?
为什么要传递? - 向下传递
向下传递啥?
为啥要传递?
为什么一下向上传?一下又向下传?
当一个类要被加载时,首先要去找类加载器。它会首先向上传递,直至传递到启动类加载器,也就是最顶层的加载器
当传递到顶后,才开始向下搜索哪个加载器能加载指定的类,进行真正的类加载
那么估计有些人就有疑问,为什么向上又向下,直接找到指定的类加载器不就ok吗?
其实,双亲委派机制是一种安全机制。
确定唯一性,任何一个类判断是否相等,还需要判断是否是同一个类加载器加载的。
同时,它能够有效避免源码被污染。看下面的例子
package java.lang;
public class String {
public void test(){
System.out.println("test");
}
public static void main(String[] args) {
}
}
试想,上面的代码是用户自定的java.lang.String,它能否执行成功呢?
答案肯定是不行的,如果可以,那java语言的源码岂不是可以随意污染。执行结果如下
意思就是说在java.lang.String中没有main方法。那我们看下官方提供的源码
可以看到在源码中,搜索main方法也是不存在的。
那有人就会说,我自己写的java.lang.String中不是有吗?这时候就要和双亲委派有关了
看个图就明白了
由于是自上到下加载,所以加载到启动器加载器时,就发现有同名包rt.jar中有java.lang.String
所以加载到的String不是用户自定义的,而是rt.jar包中的String类,所以才会报错,显示String中没有main方法
双亲委派机制的打破
上面讲了为什么要有双亲委派机制,为什么后面又要打破呢???
拿tomcat举例子吧
tomcat是web容器的一种,在tomcat中,往往一个class文件会被加载多次,因为不同用户每次访问都要加载一次,这样就会导致tomcat中会出现类冲突。那怎么避免冲突呢?
上面讲到标识唯一性,就是表示类的时候,类加载器也算是标识的一部分,所以对同一个class文件进行不同类加载器进行加载就是不同的类
关于打破双亲委派的参考链接
https://zhuanlan.zhihu.com/p/185612299