Java面试题之类加载器有哪些?什么是双亲委派模型
类加载器有哪些:
1、启动类加载器(Bootstrap ClassLoader):这个类加载器负责将存放在<JAVA_HOME>\lib目录中的,或被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的(例如rt.jar)类库加载到虚拟机内存中;
2、扩展类加载器(Extension ClassLoader):它负责加载<JAVA_HOME>\lib\ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载器;
3、应用程序类加载器(Application ClassLoader):由于这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也称为系统类加载器。它负责加载用户类路径(claspath)上所指定的类库,开发者可以直接使用这个类加载器。
4、线程上下文类加载器,面试的时候知道的也可以说下,它是为了解决基础类掉调用回用户代码而引入的设计,也就是兼容双亲委派模型的缺陷。
类加载器双亲委派模型如下:
破坏双亲委派模型的三大情况:
1、双亲委派模型的第一次“被破坏”是发生在双亲委派模型出现之前——即JDK1.2发布之前;
2、双亲委派模型的第二次“被破坏”是由于模型自身的缺陷导致的;
一个典型的例子便是JNDI服务,JNDI现在已经是Java的标准服务,它的代码由启动类加载器去加载(在JDK1.3时放进去的rt.jar),但JNDI的目的就是对资源进行集中管理和查找,它需要调用由独立厂商实现并部署在应用程序的Classpath下的JNDI接口提供者(SPI)的代码,但启动类记载不可能“认识”这些代码?
为了解决这个问题,Java设计团队只好引入了一个不太优雅的设计,线程上下文类加载器。这个类加载器可以通过java.lang.Thread类的setContextClassLoader方法设置,如果创建线程时还未设置,它将从父线程中继承一个,如果在应用程序的全局范围内都没有设置过的话,那这个类加载器默认就是应用程序类加载器。
有了这个线程上下文来加载器,就可以做一些“舞弊”的事情了,JNDI服务使用这个县城上下文类加载器去加载所需要的SPI代码,也就是父类加载器请求子类加载器去完成类加载器的动作,这种行为实际上打通了双亲委派模型的层次结构来逆向使用类加载器,实际上已经违背了双亲委派模型的一般性原则;
java中所有涉及SPI的加载懂基本上都采用这种方式,例如JNDI、JDBC、JCE、JAXB和JBI等。
3、双亲委派模型的第三次“被破坏”是由于用户对程序动态性的追求而导致的,即热部署(OSGI实现模块化热部署)