类加载器是把编译后的class文件加载到内存,加载器可以分为启动类加载器和其他类加载器,而其他类加载器有可以分为扩展类加载器和应用程序类加载器

启动类加载器(BootStrap ClassLoader):加载java_home/lib或者指定目录下的类库文件,由封C++语言编写实现。

扩展类加载器(Extension ClassLoader):是加载java_home/lib/ext或指定目录下的类库文件,是用java语言实现的。

应用程序类加载器(Application ClassLoader):负责用户类路径ClassPath下所指定的类库,开发可以直接使用这个类加载器,若没有指定自定义的类加载器,这个一般是默认的类加载器。

对类文件进行加载时,是按照双亲委托模式加载的,如下图所示:

以上图是说说明加载类的委托顺序,要求除了顶层的启动类加载器外,其余的类加载器都有自己的父类,一般通过组合的方式复用父加载器的代码。

 

工作过程:一个类加载收到了类加载请求,不会自己去尝试加载这类,而是委托给父加载器去完成加载,依次递归委托给上级父类加载器,最终会传递到顶层的启动类加载器中。

       除非父加载器反馈自己无法实现加载(比如没有找到这类)时,子加载器才会尝试自己去加载。

好处:具有优先级的层次关系,若没有优先级加载方式,则各个加载器加载同一个文件,并放在ClassPath下,系统将会出现不同版本的类文件,程序将无法分清类是否是一个加载的文件。

      保障程序的稳定性,并且实现简单。

 

这种加载模式并不是强制的,而是java设计者推荐使用的一种类加载器实现技术。大部分遵循这个规则,但也有例外,如下所示:

1)双亲委托模式是在jdk1.2版本中,而在jdk1.1版本中,类加载器和抽象类已经存在,面对已经存在的用户自定义的类加载,为了向前兼容,添加新的protected方法findClass(),以前直接继承ClassLoader          类,复写loadClass()方法即可,jdk1.2之后就不提倡复写loadClass()方法,而是写到findClass()方法中,这样在父类调用失败时在调用自己的findClass方法。

2)双亲委托模型解决了基础类的统一问题,基础类作为被用户代码调用的API,但若是由基础类去调用用户代码怎么办?比如JNDI(JNDI目的就是对资源进行集中管理和查找)的接口代码,启动类加载器不识    别这些代码,为了解决这个问题,引入了线程上下文,用这个去加载启动类加载器识别不了的代码。

3)希望应用程序就像外设那样,不用重启就能使用。而热部署就是不用重新启动应用程序就可以进行程序的部署,不在依托父加载器,而是在平级的类加载器中进行的。

posted on 2019-03-05 10:46  奋斗的小鸟gogogo  阅读(209)  评论(0编辑  收藏  举报