`
jukyoc
  • 浏览: 13126 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ClassLoader(二)详细

    博客分类:
  • JAVA
 
阅读更多
java classLoader 体系结构

发表于:2009年6月29日 | 分类:java | 标签: architecture, classloader | views(11,538)
版权信息: 可以任意转载, 转载时请务必以超链接形式标明文章原文出处, 即下面的声明.

原文出处:http://blog.chenlb.com/2009/06/java-classloader-architecture.html

jvm classLoader architecture:

Bootstrap ClassLoader/启动类加载器
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。
Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。
System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。
User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。
类加载器的特性:

每个ClassLoader都维护了一份自己的名称空间, 同一个名称空间里不能出现两个同名的类。
为了实现java安全沙箱模型顶层的类加载器安全机制, java默认采用了 " 双亲委派的加载链 " 结构。

classloader-architecture

classloader-class-diagram
类图中, BootstrapClassLoader是一个单独的java类, 其实在这里, 不应该叫他是一个java类。因为,它已经完全不用java实现了。它是在jvm启动时, 就被构造起来的, 负责java平台核心库。

自定义类加载器加载一个类的步骤


classloader-load-class
ClassLoader 类加载逻辑分析, 以下逻辑是除 BootstrapClassLoader 外的类加载器加载流程:

// 检查类是否已被装载过 
Class c = findLoadedClass(name); 
if (c == null ) { 
     // 指定类未被装载过 
     try { 
         if (parent != null ) { 
             // 如果父类加载器不为空, 则委派给父类加载 
             c = parent.loadClass(name, false ); 
         } else { 
             // 如果父类加载器为空, 则委派给启动类加载加载 
             c = findBootstrapClass0(name); 
         } 
     } catch (ClassNotFoundException e) { 
         // 启动类加载器或父类加载器抛出异常后, 当前类加载器将其 
         // 捕获, 并通过findClass方法, 由自身加载 
         c = findClass(name); 
     } 

线程上下文类加载器
java默认的线程上下文类加载器是 系统类加载器(AppClassLoader)。

// Now create the class loader to use to launch the application 
try { 
    loader = AppClassLoader.getAppClassLoader(extcl); 
} catch (IOException e) { 
    throw new InternalError( 
"Could not create application class loader" ); 
}  
 
// Also set the context class loader for the primordial thread. 
Thread.currentThread().setContextClassLoader(loader); 
以上代码摘自sun.misc.Launch的无参构造函数Launch()。

使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.
典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.
大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。
还有一些采用 hotswap 特性的框架, 也使用了线程上下文类加载器, 比如 seasar (full stack framework in japenese).

线程上下文从根本解决了一般应用不能违背双亲委派模式的问题.
使java类加载体系显得更灵活.

随着多核时代的来临, 相信多线程开发将会越来越多地进入程序员的实际编码过程中. 因此,
在编写基础设施时, 通过使用线程上下文来加载类, 应该是一个很好的选择。

当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个,
防止因为不同的类加载器, 导致类型转换异常(ClassCastException)。

为什么要使用这种双亲委托模式呢?

因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的ClassLoader。
java动态载入class的两种方式:

implicit隐式,即利用实例化才载入的特性来动态载入class
explicit显式方式,又分两种方式:
java.lang.Class的forName()方法
java.lang.ClassLoader的loadClass()方法
用Class.forName加载类

Class.forName使用的是被调用者的类加载器来加载类的。
这种特性, 证明了java类加载器中的名称空间是唯一的, 不会相互干扰。
即在一般情况下, 保证同一个类中所关联的其他类都是由当前类的类加载器所加载的。

public static Class forName(String className) 
     throws ClassNotFoundException { 
     return forName0(className, true , ClassLoader.getCallerClassLoader()); 
}  
 
/** Called after security checks have been made. */ 
private static native Class forName0(String name, boolean initialize, 
ClassLoader loader) 
     throws ClassNotFoundException; 
上面中 ClassLoader.getCallerClassLoader 就是得到调用当前forName方法的类的类加载器

static块在什么时候执行?

当调用forName(String)载入class时执行,如果调用ClassLoader.loadClass并不会执行.forName(String,false,ClassLoader)时也不会执行.
如果载入Class时没有执行static块则在第一次实例化时执行.比如new ,Class.newInstance()操作
static块仅执行一次
各个java类由哪些classLoader加载?

java类可以通过实例.getClass.getClassLoader()得知
接口由AppClassLoader(System ClassLoader,可以由ClassLoader.getSystemClassLoader()获得实例)载入
ClassLoader类由bootstrap loader载入
NoClassDefFoundError和ClassNotFoundException

NoClassDefFoundError:当java源文件已编译成.class文件,但是ClassLoader在运行期间在其搜寻路径load某个类时,没有找到.class文件则报这个错
ClassNotFoundException:试图通过一个String变量来创建一个Class类时不成功则抛出这个异常
参考:
分享到:
评论

相关推荐

    ClassLoader小例子

    下面我们将详细讨论ClassLoader的基本概念、工作流程以及如何自定义ClassLoader。 1. **ClassLoader的基本概念** - 类加载器是Java中的一个核心组件,它负责将类的.class文件加载到JVM中,并转换为可执行的Java...

    Understanding the Java ClassLoader

    为了更好地理解和利用Java的这一特性,本篇将详细介绍Java ClassLoader的作用及其工作原理,并通过构建一个示例ClassLoader来帮助读者深入理解如何自定义ClassLoader,从而扩展JVM的功能。 #### 二、ClassLoader...

    j-classloader-ltr

    在《classloader教程 --- from IBM》这篇教程中,作者Greg Travis通过一系列详细的讲解帮助读者理解Java中的类加载器(ClassLoader)。作为Java运行时系统的一个核心但常被忽视的部分,类加载器负责在运行时查找并加载...

    java ClassLoader机制详细讲解

    ClassLoader的主要任务是将类的二进制数据转换为可执行的Java对象。它使得Java具备了动态加载类的能力,这对于模块化、插件系统以及服务定位等高级功能至关重要。 ClassLoader的加载流程遵循“双亲委托模型”...

    Tomcat 5.0.18 ClassLoader source code insight

    下面,我们将详细探讨Tomcat 5.0.18版本中的ClassLoader工作原理。 首先,ClassLoaders在Java中起着至关重要的作用,它们负责查找和加载类到JVM中。Tomcat的ClassLoader设计独特,因为它需要处理Web应用程序的隔离...

    JAVA ClassLoader 讲解 (类加载器)

    #### 二、介绍 **什么是类加载器?** 类加载器是Java运行时系统中一个关键但经常被忽视的组成部分。它的主要职责是在运行时查找并加载类文件。通过创建自己的类加载器,你可以定制JVM的行为,从而完全重新定义类...

    Java_ClassLoader详解

    本文详细介绍了 Java 中的类加载器及其工作原理,包括类加载器的不同类型、类的加载过程以及类加载器与类实例化的关联。深入理解类加载机制对于开发高质量的 Java 应用程序至关重要,特别是在处理多层架构、模块化...

    java classloader讲义-淘宝网

    ### Java ClassLoader详解:以淘宝网为例...以上内容详细介绍了Java ClassLoader的基本概念、工作原理、自定义方式及其实战应用,并结合淘宝网的实际案例进行了分析,希望能够帮助读者更深入地理解和运用ClassLoaders。

    了解Java ClassLoader

    下面将详细介绍Java ClassLoader的基本概念、工作流程、类加载机制以及自定义ClassLoader。 1. **ClassLoader基本概念** - ClassLoader是一个Java类,用于动态加载Java类到JVM中。Java程序中的每个类都由某个...

    使用自定义ClassLoader解决反序列化serialVesionUID不一致问题 _ 回忆飘如雪1

    以下是几种常见方法的优缺点以及自定义`ClassLoader`的详细解释: 1. **修改序列化byte数据**: 这种方法直接修改已序列化的字节数组,替换不一致的`serialVersionUID`。优点是能够解决序列化数据本身的`...

    S18-ClassLoader类加载流程1

    本文将详细讲解类加载的流程、类加载器的层次结构以及双亲委派模型。 1. **类加载的生命周期** 类的生命周期包括7个阶段:加载、验证、准备、解析、初始化、使用和卸载。 - **加载**:从指定的位置(如类路径、...

    Java高级面试第二套2.探索JVM底层奥秘ClassLoader源码分析与案例讲解

    微信小程序详细图文教程 泉州大白网络科技 目录 一.微信小程序申请 二.服务器设置(申请、部署、域名) 1.申请服务器 2.部署服务器 3.域名申请和配置 三.小程序发布 1.下载DEMO 2.下载开发工具并安装 3.配置参数 4....

    Java Classloading Mechanism : ClassLoader & ASM & 动态字节码增强

    在本篇中,我们将详细探讨ClassLoader的工作原理、ASM库的使用以及如何利用这些工具进行动态字节码增强。 首先,我们来看Java的类加载机制。Java中的类加载主要由ClassLoader完成,它遵循“双亲委派模型”(Parents...

    Java Classloader机制用法代码解析

    本文将对 Java Classloader 机制进行详细的解析,包括 JDK 默认的 ClassLoader、双亲委托模型、自定义 ClassLoader 等相关内容。 一、JDK 默认的 ClassLoader JDK 提供了多种默认的 ClassLoader,包括 Bootstrp ...

    Java虚拟机第二版(非扫描版)

    《Java虚拟机第二版》这本书详细阐述了JVM的内部工作原理,涵盖了诸如字节码解释执行、编译优化(如即时编译JIT,Just-In-Time)、垃圾收集机制、内存区域划分等关键概念。其中,类加载子系统是JVM的重要组成部分,...

    JVM原理详细(推荐)

    1. **装载**:装载阶段是查找并加载类的二进制数据。这个过程是由 ClassLoader 和其子类完成的。类的名称由类名、包名和 ClassLoader 实例 ID 组成,用来唯一标识一个类。对于非数组类,类名即为完整的类路径;而...

    classloader-example:博客帖子

    加载是指找到类的二进制数据,通常从.class文件中获取。链接包括验证、准备和解析步骤,确保类的数据符合规范并准备就绪。初始化则执行类初始化块的代码。 Java类加载器体系结构基于委托模型,这意味着当一个类加载...

    JAVA 基础培训,JDK和JVM,核心类的介绍和使用

    #### 二、JDK的classloader机制实战 **2.1 动态加载与更新** 在某些场景下,如开发框架、插件系统等,可能需要在运行时动态加载或更新类。实现这一目标的关键在于修改类搜索路径和清空类加载器的缓存。 - 继承`...

    深入java虚拟机第二版

    《深入Java虚拟机第二版》是一本专注于Java技术体系核心的权威著作,它详细解析了Java虚拟机(JVM)的工作原理,为开发者提供了深入理解Java程序运行机制的关键知识。这本书不仅包含了源码分析,还特别优化了PDF...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第二阶段47讲、ClassLoader初始化阶段详细介绍clinit.mp4 │ 高并发编程第二阶段48讲、JVM内置三大类加载器的详细介绍.mp4 │ 高并发编程第二阶段49讲、自定义类加载器ClassLoader顺便问候了一下...

Global site tag (gtag.js) - Google Analytics