您现在的位置是:首页 >

classloader重写 classloader详细资料大全

火烧 2021-07-25 11:58:02 1062
cla loader详细资料大全 Cla loader 类加载器,用来载入Java类到 Java 虚拟机中的一种载入器。基本介绍中文名:类载入器外文名:cla loder平台:PC语言:JAVA 基础

classloader详细资料大全  

Classloader 类加载器,用来载入Java类到 Java 虚拟机中的一种载入器。

classloader重写 classloader详细资料大全

基本介绍

中文名:类载入器外文名:classloder平台:PC语言: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.ClassLoader或者它的子类。在实例化每个ClassLoader对象时,需要指定一个父对象;如果没有指定的话,系统自动指定ClassLoader.getSystemClassLoader()为父对象。 所以当创建自己的Class Loader时,只需要重载findClass()这个方法。

卸载重载

当一个javaclass被载入到JVM之后,它有没有可能被卸载呢?我们知道Win32有FreeLibrary()函式,Posix有dlclose()函式可以被调用来卸载指定的动态连线库,但是Java并没有提供一个UnloadClass()的方法来卸载指定的类。 在Java中,java class的卸载仅仅是一种对系统的最佳化,有助于减少套用对记忆体的占用。既然是一种最佳化方法,那么就完全是JVM自行决定如何实现,对Java开发人员来说是完全透明的。 在什么时候一个java class/interface会被卸载呢?Sun公司的原话是这么说的:"class or interfacemay be unloaded if and only if its class loader is unreachable. Classesloaded by the bootstrap loader may not be unloaded." 事实上我们关心的不是如何卸载类的,我们关心的是如何更新已经被载入了的类从而更新套用的功能。JSP则是一个非常典型的例子,如果一个JSP档案被更改了,套用伺服器则需要把更改后的JSP重新编译,然后载入新生成的类来回响后继的请求。 其实一个已经载入的类是无法被更新的,如果你试图用同一个ClassLoader再次载入同一个类,就会得到异常(java.lang.LinkageError: duplicate classdefinition),我们只能够重新创建一个新的ClassLoader实例来再次载入新类。至于原来已经载入的类,开发人员不必去管它,因为它可能还有实例正在被使用,只要相关的实例都被记忆体回收了,那么JVM就会在适当的时候把不会再使用的类卸载。 使用执行绪上下文类载入器, 可以在执行执行绪中, 抛弃双亲委派载入链模式, 使用执行绪上下文里的类载入器载入类. 典型的例子有, 通过执行绪上下文来载入第三方库jndi实现, 而不依赖于双亲委派. 大部分java app伺服器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。 当然, 好东西都有利弊. 使用执行绪上下文载入类, 也要注意, 保证多根需要通信的执行绪间的类载入器应该是同一个, 防止因为不同的类载入器, 导致类型转换异常(ClassCastException). 参考资料及图片来源——Understanding J2EE Application Server Class Loading Architectures  
永远跟党走
  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!

    • 微信收款码
    • 支付宝收款码