转载

双亲委派模型详解以及脑图

双亲委派模型

定义

对于类的加载,只需要加载进内存一次就足够了.为了避免重复加载,当父 ClassLoader 已经加载了该类的时候,就没有必要子 ClassLoader 再加载一次。这种加载器之间的层次关系,就叫做双亲委派模型(Parents Delegation Model)。

描述

  • 双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应该有自己的父(没有继承关系,而是使用组合关系来组织他们 的层级关系)类加载器。

  • 如果一个类加载器收到了类加载的请求,这个类加载器先从自己已经加载的类中查询是否此类已经加载,如果已经加载直接返回原来已经加载的类。

  • 如果没有加载,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去 完成。

  • 每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,当父类加载器反馈自己不能完成 这个加载请求(自己负责的范围内没有这个类),子类加载器才会尝试自己去加载。

举例

尝试定义一个 java.lang.Object 类,可以正常编译,但是永远无法被加载运行.即使自定义了自己的类加载器.强行用 defineClass()方法去加载一个以”java.lang”开头的类也不会成功。

总结

双亲委派模型有一个显而易见的好处就是 java 类随着它的类加载器一起具备了一种带有优先级的层次关系.比如 java.lang.Object 类,无论是哪个类加载器接收到加载的请求,都会委派给启动类加载器去加载.因此 Object 类在程序中都是同一个类. 相反,如果没有双亲委派,任何一个类加载器收到请求都自己去加载,那么系统中将会出现多个不同的 Object 类,java 类型体系的最基本 的行为就无法保证了。

破坏双亲委派模型

描述

  • 1、在我们自定义类加载器的时候,可以复写父类 ClassLoader 的 loadClass 方法,这样就直接破坏了双亲委派模型.到后面 JDK1.2 之后,为了解决这个问题以及兼容问题,提供了一个 findClass()方法。

  • 2、如果 API 中的基础类想要调用用户的代码(JNDI/JDBC 等),此时双亲委派模型就不能完成.为了解决这个问题,java 设计团队只好 使用一个不优雅的设计方案:Thread 的上下文类加载器,默认就是应用程序的类加载器。

  • 3、由于程序动态性的发展,希望应用程序不用重启就可以加载最新的字节码文件.此时就需要破坏双亲委派模型。

总结

  • 1、自定义类加载器,复写 loadClass 方法。

  • 2、使用线程的上下文类加载器对象。

脑图

双亲委派模型详解以及脑图

双亲委派模型详解以及脑图

原文  https://juejin.im/post/5ef0b194f265da02ac74ccb4
正文到此结束
Loading...