双亲委托模型

2020-06-24  本文已影响0人  陈桐Caliburn

1、双亲委托模型

从java虚拟机角度讲,只存在两种类加载器
1、启动类加载器 BootstrapClassLoader,是C++语言实现
2、其他类加载器,java实现

从开发人员角度讲,划分三类
1、启动类加载器(BootstrapClassLoader)
负责加载JAVA_HOME/lib目录下或被-Xbootclasspath指定路径

2、扩展类加载器(ExtensionClassLoader)
负责加载<JAVA_HOME>\lib\ext

3、应用类加载器(ApplicationClassLoader)
负责加载用户类路径上的指定类库

双亲委托模型

类加载器之间父子关系是以组合关系来复用父加载器代码

双亲委托工作流程:
如果一个类加载器收到类加载请求,他首先不会自己尝试加载这个类,而是将这个请求委派给父类加载器完成,每一个层次加载器都是如此,直到委托到启动类加载器,只有父类反馈无法完成请求,子类才尝试加载

2、为什么使用双亲委托

1、因为可以避免重复加载,当父类已经加载该类,就没有必要让子类再加载一次。
2、考虑安全因素,如果用自定义同名类来动态替换java核心api中定义类型,存在非常大隐患,除非自定义ClassLoader搜索算法

3、JVM在搜索类中,如何判定两个class相同

1、判断两个类名是否相同
2、是否由同一个类加载器实例加载

4、代码实现

protected Class<?> loadClass(String className, boolean resolve) throws  ClassNotFoundException { 
    //首先检查类是否加载过
    Class<?> clazz = findLoadedClass(className);
    if (clazz == null) {   
        try {   
            //如果存在父节点,加载父加载器ClassLoader 
             if(parent!=null){
                 //如果没有加载过,先调用父加载器的loadClass
                 clazz = parent.loadClass(className, false);
             }else{//否则用启动类加载器
                  clazz= findBootstrapClassOrNull(className);
             }
        } catch (ClassNotFoundException e) {
            //抛出异常说明父类无法完成加载请求
            if(clazz == null){
                clazz = findClass(className);
            }
        }
    } 

    //解析class
    if(resolve){
        resolveClass(clazz)
    }

    return clazz;
}
上一篇 下一篇

猜你喜欢

热点阅读