Java类加载器

2019-01-02  本文已影响0人  青芒v5

java类加载就是把二进制class文件加载到内存然后验证、解析、初始化的过程。执行这些内容的就是有我们熟知的类加载器来实现的。

类加载器

每一个类加载器都有一个独立的类名称空间。比较两个类是否相等的前提是同一类加载器加载。

从开发人员角度来看,类加载器可以分为下面三种类型

启动类加载器 Bootstrap ClassLoader
负责加载存放在 <JAVA_HOME>\lib目录或者 -Xbootclasspath指定目录下的符合名字要求的类库(如 rt.jar)加载到虚拟机内存中。名字不符合的类库即使放到该目录下也不会被加载。

扩展类加载器 Extension ClassLoader
负责加载存放在 <JAVA_HOME>\lib\ext目录的或者 java.ext.dirs系统变量指定的目录。开发者可以直接使用。

应用程序类加载器 Application ClassLoader
负责加载用户类路径(classpath)上所指定的类库,开发者可以直接使用,一般也是程序中默认的类加载器。

双亲委派

是Java设计者推荐给开发者的一种类加载器实现方式。
大概的工作流程:如果一个类加载器收到加载请求,它先询问自己的父级加载器是否能够加载,然后依次类推,直到传到顶层的启动类加载器。当父类加载器反馈无法加载时,子加载器才会尝试自己加载。

打破双亲委派

双亲委派只是一种建议的模型,在实际运用中有很多部分不遵守该模型的例子。

  1. 用户重写loadClass()方法实现自定义加载逻辑
  2. JAVA SPI
  3. 热部署,热加载等技术
  4. OSGi(Open Service Gateway Initiative)技术是Java动态化模块化系统的一系列规范。它实现模块化热部署的关键是它自定义的类加载机制的实现。每一个程序模块都有一个自己的类加载器。

规则如下(摘自《深入累计Java虚拟机》

  1. 以 java.* 开头的类委派给父类加载器加载。(遵守双亲委派)
  2. 否则,将委派列表名单内的类委派给父类加载器加载。(遵守双亲委派)
  3. 否则,将Import列表中的类委派给Export这个类的Bundle的类加载器加载。
  4. 否则, 查找当前Bundle的classpath,使用自己的类加载器加载。
  5. 否则,查找类是否在自己的Fragment Bundle中,在的话则委派给Fragment Bundle的类加载器加载。
  6. 否则,查找Dynamic Import 列表的Bundle, 委派给对应的Bundle的类加载器加载。
  7. 否则, 类加载失败

有赞Aladdin的加载实践

为什么要搞一个Aladdin系统,在一个大集群分布式环境下,应用非常的多,所以急需要一个能够统一管理的平台,它的能力有下面几个
1.解决jar包版本冲突问题
2.统一管理jar包安全性、可靠性
3.统一管理jar包的升级

在类加载器的这个文章里,并不是要解说这个jar包管理系统,可以看下它是如何实现自己的classLoader。

Aladdin的类加载大部分是通过http或者url的方式进行,所以直接继承了UrlClassLoader。而UrlClassLoader是 ExtClassLoader的父类,所以这里已经丝毫没有双亲委派的影子了。

UrlClassLoader的功能
1.可以从文件系统加载
2.可以从jar包进行加载
3.从远程Http服务进行加载

上一篇下一篇

猜你喜欢

热点阅读