`
raymond.chen
  • 浏览: 1426045 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java的类加载机制

    博客分类:
  • Java
 
阅读更多

ClassLoader的双亲委派模型

       所有的类加载器都是有层级结构的,每个类加载器都有一个父类类加载器(通过组合实现,而不是继承),除了启动类加载器(Bootstrap ClassLoader)

 

       当一个类加载器接收到一个类加载请求时,首先将这个请求委派给它的父加载器去加载,所以每个类加载请求最终都会传递到顶层的启动类加载器,如果父加载器无法加载时,子类加载器才会去尝试自己去加载

 

        通过双亲委派模型就实现了类加载器的三个特性:

                委派(delegation):子类加载器委派给父类加载器加载

                可见性(visibility):子类加载器可访问父类加载器加载的类,父类不能访问子类加载器加载的类

                唯一性(uniqueness):可保证每个类只被加载一次

 

Java的类加载器

         启动类加载器(Bootstrap ClassLoader),是虚拟机自身的一部分

         所有其他的类加载器,独立于虚拟机外部,都继承自抽象类 java.lang.ClassLoader

 

         1、启动类加载器(Bootstrap/Primordial/NULL ClassLoader):顶层的类加载器,没有父类加载器。负责加载 /lib 目录下的,或则被 -Xbootclasspath 参数所指定路径中的,并被 JVM 识别的(仅按文件名识别,如 rt.jar,名字不符合的类库即使放在 lib 目录也不会被加载)类库加载到虚拟机内存中。所有被 Bootstrap classloader 加载的类,它的 Class.getClassLoader 方法返回的都是 null,所以也称作 NULL ClassLoader。

 

         2、扩展类加载器(Extension CLassLoader):由 sun.misc.Launcher$ExtClassLoader 实现,负责加载 <JAVA_HOME>/lib/ext 目录下,或被 java.ext.dirs 系统变量所指定的目录下的所有类库

 

         3、应用程序类加载器(Application/System ClassLoader):由 sun.misc.Launcher$AppClassLoader 实现。它是 ClassLoader.getSystemClassLoader() 方法的默认返回值,所以也称为系统类加载器(System ClassLoader)。它负责加载 classpath 下所指定的类库,如果应用程序没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

 

 

         class.getResource("/") == class.getClassLoader().getResource("")   //当前类所在classpath的根目录

                Class.getResource真正调用ClassLoader.getResource方法之前,会先获取文件的路径(path不以'/'开头时,默认是从此类所在的包下取资源;path以'/'开头时,则是从项目的ClassPath根下获取资源)。

 

                ClassLoader.getResource方法会通过双亲委派机制,先委派双亲去加载类,如果双亲没有加载到,则再由自己加载。

 

线程的上下文类加载器

         线程上下文类加载器(context class loader)是从 JDK 1.2 开始引入的。类 java.lang.Thread中的方法 getContextClassLoader()和 setContextClassLoader(ClassLoader cl)用来获取和设置线程的上下文类加载器。

 

         如果没有通过 setContextClassLoader(ClassLoader cl)方法进行设置的话,线程将继承其父线程的上下文类加载器。Java应用运行的初始线程的上下文类加载器是系统类加载器。如果不做任何的设置,那么线程的上下文类加载器默认就是系统类加载器。

 

Web容器的类加载器

         Web容器的类加载器的实现方式与一般的Java应用有所不同。不同的Web容器的实现方式也会有所不同。

         以 Apache Tomcat 来说,每个 Web 应用都有一个对应的类加载器实例。该类加载器也使用代理模式,所不同的是它是首先尝试去加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。这是 Java Servlet 规范中的推荐做法,其目的是使得 Web 应用自己的类的优先级高于 Web 容器提供的类。这种代理模式的一个例外是:Java 核心库的类是不在查找范围之内的。这也是为了保证 Java 核心库的类型安全。

 

自定义ClassLoader

对于ClassLoader,其实我们可以随心所欲的自定义它,只要重载findClass()方法就可以。

public class Test {
	public static void main(String[] args) throws Exception {
		DiskClassLoader loader = new DiskClassLoader("D:\\work\\target\\classes");
		Class<?> clazz = loader.loadClass("com.easy.ebook.bean.User");
		System.out.println(clazz);
	}
	
	static class DiskClassLoader extends ClassLoader {
	    private String mFilePath;

	    public DiskClassLoader(String mFilePath) {
	        this.mFilePath = mFilePath;
	    }

	    @Override
	    protected Class<?> findClass(String name) throws ClassNotFoundException {
	        String filepath = this.mFilePath + File.separator + name.replace('.', File.separatorChar) + ".class";
	        System.out.println(filepath);
	        
	        File file = new File(filepath);
	        try {
	            FileInputStream ins = new FileInputStream(file);
	            ByteArrayOutputStream bos = new ByteArrayOutputStream();
	            int len = 0;
	            try {
	                while((len = ins.read()) != -1) {
	                    bos.write(len);
	                }
	            } catch (IOException ioe) {
	                ioe.printStackTrace();
	            }
	            byte[] data = bos.toByteArray();
	            ins.close();
	            bos.close();
	            return defineClass(name, data, 0, data.length);
	        } catch (IOException exp) {
	            exp.printStackTrace();
	        }
	        return super.findClass(name);
	    }
	}
}

 

分享到:
评论

相关推荐

    深入研究Java类加载机制 深入研究Java类加载机制

    深入研究Java类加载机制 深入研究Java类加载机制 深入研究Java类加载机制 深入研究Java类加载机制

    java类加载机制

    java 类加载机制,课程笔记。

    java类加载机制原理与实现

    Java 类加载机制原理与实现 Java 类加载机制是 Java 虚拟机(JVM)的一部分,负责将编译后的 Java 字节码文件加载到 JVM 中,以便执行 Java 程序。类加载机制是 JVM 的核心组件之一,对 Java 程序的执行和安全性起...

    Java类加载机制.doc

    Java 类加载机制是Java平台的核心特性之一,它负责将类的字节码加载到Java虚拟机(JVM)中并转换为运行时的类对象。理解这一机制对于优化应用程序性能和解决类相关的错误至关重要。 首先,类加载的过程分为三个主要...

    Java类加载机制

    深层次剖析java的类加载机制。讲解java类加载的服装流程。

    译 Java类加载机制(二)

    Java类加载机制是Java平台核心特性之一,它负责将类的.class文件加载到JVM(Java虚拟机)中,使得程序能够运行。本篇主要基于“译 Java类加载机制(一、二)”的博客内容,深入探讨Java的类加载过程、类加载器以及...

    Java类加载机制学习1

    Java 类加载机制是Java运行时环境中的核心组成部分,它负责将`.class`文件中的字节码转换为运行时的Class对象。在这个过程中,类加载器扮演着至关重要的角色。本篇文章将深入探讨Java的双亲模型类加载机制,以及如何...

    2022年初探Java类加载机制Java教程.docx

    Java类加载机制详解 Java类加载机制是Java虚拟机(JVM)中的一种机制,负责将类从字节码文件加载到内存中,并将其转换为可执行的类对象。在Java中,类加载机制是通过ClassLoader来完成的,该机制在JDK 1.2以后变得...

    Java类加载机制 PDF 下载

    Java类加载机制是Java运行时环境中的核心组成部分,它负责将编译后的字节码(.class文件)加载到Java虚拟机(JVM)中,使得程序能够执行。这一过程涉及多个步骤,包括加载、验证、准备、解析和初始化。理解类加载...

    JAVA 类加载机制分析

    1、JVM的内存管理 理解了这一点,所有和对象相关的问题统统都能解决 2、JVM 类加载 理解了这一点,所有和Java相关的配置问题,包括各种App Server的配置,...这是一份对JAVA 类加载机制整理、分析比较全面的文章。

    java类加载机制.xmind

    该文件是JVM中关于类加载机制的知识整理的思维导图,包括类加载机制概述、类加载的生命周期、加载时机、加载过程、类加载、类的初始化和实例化等几个大方面进行了讲解,其中类加载中还对JVM三种预定义类加载器进行了...

    详解JAVA类加载机制

    详解JAVA类加载机制 JAVA类加载机制是JAVA虚拟机(JVM)的一部分,它负责将.class文件加载到内存中,并对其进行校验、转换、解析和初始化,以形成可以被JVM直接使用的JAVA类型。下面将详细介绍JAVA类加载机制的相关...

    Java类加载机制.pdf

    Java类加载机制.pdf

    Java类加载机制与反射-PPT

    Java的类加载机制:加载,连接,初始化。JAVA类加载器: Bootstrap ClassLoader : 根类加载器, Extension ClassLoader: 扩展类加载器, System ClassLoader : 系统类加载器, Java反射

    JAVA类加载机制:探索虚拟世界的大门

    JAVA类加载机制:探索虚拟世界的大门

    Java 类加载机制 ClassLoader Class.forName.pdf

    java 类加载机制 ClassLoader Class.forName.pdf

    通过面试题解析 Java 类加载机制

    Java 类加载机制 Java 类加载机制是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。下面我们来学习 Java 类加载机制的基础知识,然后再实战分析几...

Global site tag (gtag.js) - Google Analytics