赞
踩
第一次知道何为打破双亲委派机制是通过阅读周志明的《深入理解Java虚拟机》,我们知道双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。每个类加载器都是如此,只有在父类加载器在自己的搜索范围内找不到指定类时,子类加载器才会尝试自己去加载。【这里的“父类”只是名义上的父类,而不是真的是继承上父子关系】
这种模型要求,除了顶层的启动类加载器外,其他的类加载器都要有自己的父类加载器。假如有一个类要加载进来,一个类加载器并不会马上尝试自己将其加载,而是委派给父类加载器,父类加载器收到后又尝试委派给其父类加载器,以此类推,直到委派给启动类加载器,这样一层一层往上委派。只有当父类加载器反馈自己没法完成这个加载时,子加载器才会尝试自己加载。通过这个机制,保证了 Java 应用所使用的都是同一个版本的 Java 核心库的类,同时这个机制也保证了安全性。设想如果应用程序类加载器想要加载一个有破坏性的 java.lang.System 类,双亲委派模型会一层层向上委派,最终委派给启动类加载器,而启动类加载器检查到缓存中已经有了这个类,并不会再加载这个有破坏性的 System 类。
另外,类加载器还拥有全盘负责机制,即当一个类加载器加载一个类时,这个类所依赖的、引用的其他所有类都由这个类加载器加载,除非在程序中显式地指定另外一个类加载器加载。
在 Java 中,我们用完全匹配类名来标识一个类,即用包名和类名。而在 JVM 中,一个类由完全匹配类名和一个类加载器的实例 ID 作为唯一标识。也就是说,同一个虚拟机可以有两个包名、类名都相同的类,只要它们由两个不同的类加载器加载。当我们在 Java 中说两个类是否相等时,必须在针对同一个类加载器加载的前提下才有意义,否则,就算是同样的字节码,由不同的类加载器加载,这两个类也不是相等的。这种特征为我们提供了隔离机制,在 Tomcat 服务器中就使用到了这样的隔离机制。
在书中我们可以知道双亲委派模型破坏历史,以下是从书上摘抄下来
jvm自带的三个类加载器所加载的路径如下
Bootstrap ClassLoader————jdk/jre/lib/ 目录下 Extension
ClassLoader————jdk/jre/lib/ext/ 目录下
Application ClassLoader————ClassPath路径下
双亲委派工作流程
①、当Application ClassLoader 收到一个类加载请求时,他首先不会自己去尝试加载这个类,而是将这个请求委派给父类加载器Extension ClassLoader去完成。
②、当Extension ClassLoader收到一个类加载请求时,他首先也不会自己去尝试加载这个类,而是将请求委派给父类加载器Bootstrap ClassLoader去完成。
③、如果Bootstrap ClassLoader加载失败(在<JAVA_HOME>\lib中未找到所需类),就会让Extension ClassLoader尝试加载。
④、如果Extension ClassLoader也加载失败,就会使用Application ClassLoader加载。
⑤、如果Application ClassLoader也加载失败,就会使用自定义加载器去尝试加载。
⑥、如果均加载失败,就会抛出ClassNotFoundException异常。
那么那些地方会应用到打破双亲委派机制这样的情况呢?
答:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。