`

常用的ClassLoader的加载范围

阅读更多
WebAppClassLoader装载器装作文件的范围:
会加载WEB-INF/lib/*和WEB-INF/classes/*
如果加载失败会交给上级AppClassLoader进行加载。
AppClassLoader装载器装作文件的范围:
加载的顺序为
JRE\lib\* => JRE\lib\ext\* => JRE\classes\* => CLASSPATH\*
如果加载失败会再交给上层斤进行加载。

Tomcat负责Web应用的类加载的是org.apache.catalina.loader.WebappClassLoader,它有几个比较重要的方法:findClass(),loadClass(),findClassInternal(),findResourceInternal().

   WebappClassLoader类加载器被用来加载一个类的时候,loadClass()会被调用,loadClass()则调用findClass()。后两个方法是WebappClassLoader的私有方法,findClass()调用findClassInternal()来创建class对象,而findClassInternal()则需要findResourceInternal()来查找.class文件。

通常自己实现类记载器只要实现findclass即可,这里为了实现特殊目的而override了loadClass().


即loadClass(name)(入口)->findClass(name)->findClassInternal(name)(用于创建class对象)->findResourceInternal()(寻找.class文件)

下面是自定义类加载器
引用自http://blog.sina.com.cn/s/blog_4d398d670100dmui.html
下面是精简过的代码(去除了几乎全部关于log、异常和安全控制的代码):

loadClass:

    public Class loadClass(String name, boolean resolve)
            throws ClassNotFoundException {
        Class clazz = null;
        // (0) 先从自己的缓存中查找,有则返回,无则继续
        clazz = findLoadedClass0(name);
        if (clazz != null) {
            if (resolve) resolveClass(clazz);           
            return (clazz);
        }
        // (0.1) 再从parent的缓存中查找
        clazz = findLoadedClass(name);
        if (clazz != null) {
            if (resolve) resolveClass(clazz);
            return (clazz);
        }
        // (0.2) 缓存中没有,则首先使用system类加载器来加载
        clazz = system.loadClass(name);
         if (clazz != null) {
             if (resolve) resolveClass(clazz);
             return (clazz);
         }
        //判断是否需要先让parent代理
        boolean delegateLoad = delegate || filter(name);
        // (1) 先让parent加载,通常delegateLoad == false,即这一步不会执行

        if (delegateLoad) {
            ClassLoader loader = parent;
            if (loader == null)
                loader = system;
            clazz = loader.loadClass(name);
            if (clazz != null) {
                if (resolve) resolveClass(clazz);
                return (clazz);
            }
        }
        // (2) delegateLoad == false 或者 parent加载失败,调用自身的加载机制
        clazz = findClass(name);
        if (clazz != null) {
            if (resolve) resolveClass(clazz);
            return (clazz);
        }
        // (3) 自己加载失败,则请求parent代理加载

        if (!delegateLoad) {
            ClassLoader loader = parent;
            if (loader == null)
                loader = system;
            clazz = loader.loadClass(name);
            if (clazz != null) {
                return (clazz);
            }
        }
        throw new ClassNotFoundException(name);
    }




findClass:

public Class findClass(String name) throws ClassNotFoundException {
        // 先试图自己加载类,找不到则请求parent来加载
        // 注意这点和java默认的双亲委托模式不同
        Class clazz = null;
        clazz = findClassInternal(name);
        if ((clazz == null) && hasExternalRepositories) {
            synchronized (this) {
                clazz = super.findClass(name);
            }
        }
        if (clazz == null) {
            throw new ClassNotFoundException(name);
        }

        return (clazz);
    }

分享到:
评论

相关推荐

    java的ClassLoader类加载器机制

    每个类加载器都有其特定的加载范围和优先级,确保了 Java 类的正确加载和使用。 类加载器的工作原理可以分为三个阶段:加载、链接和初始化。在加载阶段,类加载器会查找和加载指定的类。在链接阶段,类加载器会对...

    Android Classloader测试demo

    在Android系统中,Classloader(类加载器)是至关重要的组件,它负责查找并加载Java类到Dalvik或ART运行时环境。这个测试demo是为了帮助开发者深入理解Android中两种主要的类加载器:DexClassLoader和...

    java类加载器

    根据类加载器的来源和作用范围,可以将其分为三种类型: 1. **启动类加载器(Bootstrap ClassLoader)** - **实现语言**:C++ - **位置**:属于JVM的一部分 - **作用**:加载JVM自身工作需要的类,如`rt.jar`等...

    class文件热加载,上传class文件实现热加载

    - Bootstrap ClassLoader加载JDK核心库(rt.jar),Extension ClassLoader加载JRE扩展目录下的jar,AppClassLoader加载应用的类路径(classpath)中的类。 2. **自定义类加载器**: - 开发者可以创建自定义类加载...

    classloader做的一个热部署

    eclipse工程格式 博文链接:https://aga.iteye.com/blog/200818

    动态加载jar包

    如果依赖是动态加载的jar包,那么它们可能需要有自己的ClassLoader来加载,以便于管理各自的类加载范围,避免命名冲突。此外,如果第三方库也依赖其他库,我们还需要处理这些依赖的嵌套加载。 为了更好地管理和组织...

    14.类加载器1

    1. **加载范围**:启动类加载器加载的类库通常包括`rt.jar`等核心类库,这些类库对Java虚拟机至关重要。 2. **加载方式**:启动类加载器是通过C++语言实现的,而非Java语言。 3. **委托机制**:用户自定义类加载器若...

    携程动态加载框架

    这通常涉及到类加载器(ClassLoader)的定制,以确保插件类能够在不干扰主程序的前提下被正确加载。 2. **接口通信**:主程序与插件之间需要通过定义好的接口进行通信,以协调各自的行为。这可能涉及AIDL(Android ...

    揭示Java类加载内幕(code)

    例如,在`classloader.part1.basics`这个部分,可能涵盖了自定义类加载器的基础知识,包括如何继承`java.lang.ClassLoader`,重写`loadClass()`方法,以及如何管理类的加载范围。 总的来说,理解Java类加载机制不仅...

    Java类加载及SPI机制.pdf

    即如果一个类加载器收到了类加载的请求,它首先不会自己尝试去加载这个类,而是将加载请求委托给父类加载器去完成,每一层都是如此,只有当父类加载器在它的搜索范围中没有找到所需的类时,子类加载器才会尝试自己去...

    Java类加载器机制与模型.pdf

    类加载器之间形成了一种层次结构,称为**类加载器层次体系**,每个类加载器都有明确的职责范围,共同协作完成整个JVM的类加载工作。 类加载器机制对于理解和解决Java中的问题,如类冲突、安全控制以及插件系统设计...

    Java类加载机制

    Java 中存在多种类型的类加载器,每种类加载器都有其特定的作用范围: 1. **引导类加载器(Bootstrap Class Loader)**:这是系统级的类加载器,它负责加载 Java 核心类库,如 `java.lang.Object`。由于这是一个...

    2015网易校招JAVA开发工程师.pdf

    Bootstrap ClassLoader加载Java的核心库,Extension ClassLoader加载Java的扩展库,而Application ClassLoader则加载应用类路径下的类。每个类加载器都有自己的加载范围,并遵循双亲委派模型,即当一个类加载器收到...

    Java安全技术.pptx

    Bootstrap ClassLoader加载的是JVM自带的核心类库,System ClassLoader加载的是系统类库,而用户自定义的类则由自定义的ClassLoader加载,它们各自具有不同的权限范围。 字节码验证器(Bytecode Verifier)是Java...

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

    3. **来源多样化**:可以从非标准位置,如数据库、网络资源中加载Java类,扩大了类的来源范围。 总之,深入理解JDK的classloader机制对于掌握Java编程至关重要,它不仅是Java程序运行的基础,也是实现高级编程技术...

    Java类加载机制实现流程及原理详解

    它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该...

    JVM 运行时数据区域,垃圾回收机制,类加载机制三大功能详解.docx

    类加载机制还包括类加载器体系,其中主要包括引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。这些类加载器形成了类加载器的层次结构,...

    Java语言中的自定义类加载器实例解析

    由于每个`FileClassLoader`实例都有自己的加载范围,所以即使加载的是同一个类,它们之间也是不共享的,这体现在`Demo`类的`hashCode`值上。如果两个`FileClassLoader`实例加载同一个类,它们将分别返回不同的`...

    URLClassLoader中指定目录和jar的问题

    `URLClassLoader`继承自`java.lang.ClassLoader`,主要负责从网络、文件系统或任何其他可以通过URL访问的资源中加载类。它的核心功能在于`addURL`方法,这个方法允许我们动态地向类加载器添加新的URL,从而扩展类和...

Global site tag (gtag.js) - Google Analytics