classloader类加载器_基于java类的加载方式详解
基础概念
classloader 类加载器,用来加载 java 类到 java 虚拟机中。与普通程序不同的是。java程序(class文件)并不是本地的可执行程序。当运行java程序时,首先运行jvm(java虚拟机),然后再把java class加载到jvm里头运行,负责加载java class的这部分就叫做class loader。
jvm本身包含了一个classloader称为bootstrap classloader,和jvm一样,bootstrapclassloader是用本地代码实现的,它负责加载核心javaclass(即所有java.*开头的类)。另外jvm还会提供两个classloader,它们都是用java语言编写的,由bootstrapclassloader加载;其中extension classloader负责加载扩展的javaclass(例如所有javax.*开头的类和存放在jre的ext目录下的类),applicationclassloader负责加载应用程序自身的类。
当运行一个程序的时候,jvm启动,运行bootstrapclassloader,该classloader加载java核心api(extclassloader和appclassloader也在此时被加载),然后调用extclassloader加载扩展api,最后appclassloader加载classpath目录下定义的class,这就是一个程序最基本的加载流程。
注: 学classloader看osgi程序应用
什么时候jvm会使用classloader加载一个类呢?当你使用java去执行一个类,jvm使用applicationclassloader加载这个类;然后如果类a引用了类b,不管是直接引用还是用class.forname()引用,jvm就会找到加载类a的classloader,并用这个classloader来加载类b。jvm按照运行时的有效执行语句,来决定是否需要装载新类,从而装载尽可能少的类,这一点和编译类是不相同的。
why use your own classloader?
似乎jvm自身的classloader已经足够了,为什么我们还需要创建自己的classloader呢?
因为jvm自带的classloader只是懂得从本地文件系统加载标准的java class文件,如果编写你自己的classloader,你可以做到:
1)在执行非置信代码之前,自动验证数字签名
2)动态地创建符合用户特定需要的定制化构建类
3)从特定的场所取得java class,例如数据库中
4) 等等
事实上当使用applet的时候,就用到了特定的classloader,因为这时需要从网络上加载java class,并且要检查相关的安全信息。
应用服务器大都使用了classloader技术,即使你不需要创建自己的classloader,了解其原理也有助于更好地部署自己的应用。
重点注明:其实一个已经加载的类是无法被更新的,如果你试图用同一个classloader再次加载同一个类,就会得到异常(java.lang.linkageerror: duplicate classdefinition),我们只能够重新创建一个新的classloader实例来再次加载新类。至于原来已经加载的类,开发人员不必去管它,因为它可能还有实例正在被使用,只要相关的实例都被内存回收了,那么jvm就会在适当的时候把不会再使用的类卸载。
绝大部分java程序都会使用3种系统提供的类加载器
1.启动类加载器(bootstrap classloader),负责将存在<java_home>\lib目录中的,或被-xbootclasspath参数所指定的路径中的,并且是虚拟机识别的类库加载到虚拟机里.注意是按照文件名识别,如rt.jar,名字不符合的类库即使放在lib目录中也不会被加载。
2.扩展类加载器(extclassloader),它负责<java_home>\lib\ext目录中的,或被java.ext.dirs系统变量所指定的路径中的所有类库.
3.应用程序类加载器(app-classloader),通过cassloader.getsystemclassloader()获取,它负责加载用户类路径(classpath)上所指定的类库,一般情况下这个是程序中默认的类加载器.
双亲委托模式 是java设计者推荐给开发者的一种类加载实现方式.双亲委托模型的工作过程是:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成.每一层次的类加载器都是如此,因此所有的加载请求最终都会传送到顶层的启动类加载器中,只有当父类加载器没有找到所需的类时,子加载器才会尝试自己去加载。双亲模式的好处是java类随着它的类加载器一起具备了一种带优先级的层次关系。例如类object,存放在rt.jar中,无论哪个类加载器加载这个类,最终都是委派给处于模型最顶端的启动类加载,因此object类在程序使用多种类加载器环境中依然能保证是同一个类。相反,如果没有使用双亲模型,就可能出现用户自己编写一个object类,导致系统中出现多个不同的object类,这样java类型体系中最基础的行为也就无法保证。
以上这篇classloader类加载器_基于java类的加载方式详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
classloader类加载器_基于java类的加载方式详解
-
【转】Java类加载器的工作原理 博客分类: JVM java虚拟机 jvm 类加载
-
【转】Java类加载器的工作原理 博客分类: JVM java虚拟机 jvm 类加载
-
JVM理论与实践【类加载器基础】 博客分类: Java jvm类加载器classloader
-
根类加载器的一个特性 博客分类: 原创 Java虚拟机SUNCC++
-
类的加载ClassLoader 博客分类: Java
-
类的加载ClassLoader 博客分类: Java
-
举例讲解Java的内部类与类的加载器
-
深入解析Java中的Class Loader类加载器
-
举例讲解Java的内部类与类的加载器