`

常用的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);
    }

分享到:
评论

相关推荐

    classloader做的一个热部署

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

    Android插件框架Android-Plugin-Framework.zip

    具体public.xml如何编写,可参考PluginMain/res/values/public.xml 以及 PluginTest/res/values/public.xml俩个文件,它们是分别用来固定宿主程序和插件程序资源id的范围的。 4、插件apk的Context 构造一个...

    Java 2平台安全技术-结构,API设计和实现

    1.8 Java安全性的适用范围 11 第2章 Java语言的基本安全特点 12 2.1 Java语言和平台 12 2.2 基本安全结构 13 2.3 字节代码验证和类型安全 14 2.4 签名应用小程序 15 2.5 关于安全错误及其修复的简要历史 16 第3章 ...

    JAVA 2平台安全技术-结构,API设计和实现

    1.8 Java安全性的适用范围 11 第2章 Java语言的基本安全特点 12 2.1 Java语言和平台 12 2.2 基本安全结构 13 2.3 字节代码验证和类型安全 14 2.4 签名应用小程序 15 2.5 关于安全错误及其修复的简要历史 16 第3章 ...

    超级有影响力霸气的Java面试题大全文档

    assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...

    day021-反射和注解笔记和代码.rar

    loader:可以指定一个类加载器加载字节码文件 2. 全限定类名.class 3. 对象名.getClass() Class类中方法newInstance():创建当前字节码对象(只能调用无参且是public修饰的构造...

    JAVA面试题最全集

    37.classloader中,JDK的API、Classpath中的同web-inf中的class加载方式有什么区别? 38.列举三种以上垃圾回收算法,并比较其优缺点? 39.编写代码实现一个线程池 40.描述一下JVM加载class文件的原理机制? 41....

    java 面试题 总结

    assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...

    Spring.3.x企业应用开发实战(完整版).part2

    4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean定义信息 4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 不同配置方式比较 4.13 小结 第5章 Spring容器高级主题 5.1 ...

    Spring3.x企业应用开发实战(完整版) part1

    4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean定义信息 4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 不同配置方式比较 4.13 小结 第5章 Spring容器高级主题 5.1 ...

    java核心知识点整理.pdf

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM .........................

    JAVA核心知识点整理(有效)

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................

Global site tag (gtag.js) - Google Analytics