双亲委派模型

一、定义

双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器,这里的父子关系一般不会以继承的关系实现,而是使用组合关系来复用父加载器的代码。

优点:1. Java类随着类加载器一起具备了带有优先级的层次关系。

2. 避免类的重复加载

二、实现

如果一个类加载器收到了一个类加载的请求,首先检查是否已经被加载过,如果没有则调用父加载器的loadClass()方法,若父加载器为空,则默认使用启动类加载器作为父加载器。如果父类加载失败,则抛出ClassNotFoundException异常后,再调用自己的findClass()方法进行加载。

三、破坏双亲委派模型

双亲委派模型并不是一个强制性的约束模型,而是Java设计者推荐给开发者的实现方式。

双亲委派模型主要出现过3次“被破坏”情况。

1. 第一次被破坏发生在双亲委派模型出现之前,即JDK1.2发布之前。因为类加载器和抽象类java.lang.classLoader在JDK1.0时已经存在,设计者为了向前兼容,在JDK1.2之后的java.lang.ClassLoader添加了一个新的protected方法的findClass()方法,该方法中实现的是自己的类加载逻辑,而loadClass()方法中实现的是双亲委派模型的具体逻辑。在loadClass()方法的逻辑里如果父类加载器加载失败,则调用自己的findClass()方法来完成加载。

2. 第二次被破坏是由于模型自身缺陷导致的。在双亲委派模型中,越基础的类由越上层的类加载器进行加载,但如果基础类又要调回用户的代码呢?比如JNDI服务,它的代码由启动类加载器加载,但JNDI是对资源进行集中管理和查找,它需要调用由独立厂商实现并部署在应用程序的ClassPath下的JNDI接口提供者的代码,但启动类加载器不可能认识这些代码。为此,Java设计者们引入了一个线程上下文类加载器。JNDI可以使用它加载所需要的SPI代码。类似还有JDBC、JCE等。

3. 第三次破坏是由于用户对程序动态性的追求导致的。比如OSGI,它实现模块化热部署的关键则是它自定义的类加载器机制的实现,每一个程序模块都有一个自己的类加载器,当需要更换一个模块时,就把模块连同类加载器一起换掉以实现代码的热替换。在OSGi环境下,类加载器不再是双亲委派模型中的树状结构,而是进一步发展为更加复杂的网状结构。

你可能感兴趣的:(双亲委派模型)