破坏双亲委派模型

JVM

第一次破坏是在jdk 1.2之前,用户自定义的类加载器都是重写Classloader中的loadClass方法,这样就导致每个自定义的类加载器其实是在使用自己的loadClass方法中的加载机制来进行加载,这种模式当然是不符合双亲委派机制的,也是无法保证同一个类在jvm中的唯一性的。为了向前兼容,java官方在Classloader中添加了findClass方法,用户只需要重新这个findClass方法,在loadClass方法的逻辑里,如果父类加载失败的时候,才会调用自己的findClass方法来完成类加载,这样就保证了写出的类加载器是符合双亲委派机制的。

第二次的破坏是由模型本身的缺陷导致的,根类加载器加载了基础代码,但是基础代码中有可能调用了用户的代码,但是对于根类加载器而言是不认识用户的代码的。

1
那么这时候java团队使用了一个不太优雅的设计:线程上下文类加载器。这个类加载器可以通过Thread类的setContextClassLoader方法进行设置,如果创建线程时还未设置,它就从父线程继承一个,如果在应用全局范围内都没有设置过的话,那这个类加载器默认就是应用程序类加载器。

利用这个线程上下文类加载器傅,父类加载器请求子类加载器去加载某些自己识别不了的类。

java中基本所有涉及spi的加载动作基本上都采用了这种方式,例如jndi,jdbc等。

第三次的破坏是因为用户对于程序的动态性追求,诸如:代码热替换,模块热部署。
目前业界Java模块化的标准是OSGI。而OSGI实现模块热部署的关键是他自己的类加载机制:每个程序模块(bundle)都有自己的类加载器,需要更换程序(bundle)的时候,连同类加载器一起替换,以实现代码的热部署。

和双亲委派模式的树状结构不同,OSGI的加载过程是一个网状结构。OSGI的加载步骤是这样的:
具体的加载过程待解决。

参考链接:《深入理解jvm》读书笔记之——类加载器

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器