JAVA双亲委派模型

2024-06-12 10:32

JAVA双亲委派模型-Parent Delegation Model

  • 类加载器层次结构:在 Java 类加载器中,存在一个层次结构,由多个类加载器按照特定的顺序组成。这个层次结构通常被称为类加载器链。

  • 父子关系:双亲委派模型中,每个类加载器都有一个父类加载器(除了根类加载器),它们之间通过组合关系建立起层次结构。一个类加载器的父加载器通常是其上一级的加载器。

  • 加载优先级:当一个类加载器需要加载一个类时,它首先将加载请求委派给其父类加载器。如果父加载器能够加载该类,那么就直接返回该类;否则,才由子加载器尝试加载。这样一层一层的委派下去,直到父加载器无法加载或者到达最顶层的启动类加载器。

  • 避免重复加载:双亲委派模型的核心思想是避免重复加载类。在加载过程中,如果某个类已经由父类加载器加载过了,那么子类加载器就不再加载,直接使用父加载器已加载的版本。这样能够确保同一个类在内存中只有一份,避免了类的重复定义和冲突。

  • 安全性保证:双亲委派模型也提供了一定的安全性保证。通过设置不同的类加载器层次结构,可以控制类加载的权限。核心的 Java API 类库通常由启动类加载器加载,而应用程序自定义的类则由应用程序类加载器加载。这样,核心类库的类无法被重新定义或篡改,保障了Java平台的稳定和安全。

  • 自定义类加载器:双亲委派模型也为自定义类加载器提供了基础。通过继承 ClassLoader 类并重写其方法,我们可以自定义类加载器,实现特定的类加载策略。自定义类加载器可以在加载类的过程中修改默认的委派行为,实现一些特殊需求。

 

 

关键类java.lang.ClassLoader

自定义类加载器

/***
 *从任意指定的某个目录中读取字节码类文件,然后创建对应的类
 */
public class CustomClassLoader  extends ClassLoader{


    static {
        //当前的classLoader可并行加载不同的类
        registerAsParallelCapable();
    }

    //指定的字节码类文件所在的目录路径
    private final String customPath;

    //构造函数,默认parent classloader是AppClassLoader
   public CustomClassLoader(String customPath){
        if(!customPath.isEmpty() && customPath.charAt(customPath.length() - 1)!= File.separatorChar){
            customPath+=File.separatorChar;
        }
        this.customPath=customPath;
    }

    //构造函数,指定一个parent ClassLoader
    public CustomClassLoader(String customPath,ClassLoader parent){
       super(parent);
        if(!customPath.isEmpty() && customPath.charAt(customPath.length() - 1)!= File.separatorChar){
            customPath+=File.separatorChar;
        }
        this.customPath=customPath;
    }

    //覆盖父类的findClass()方法 从指定的目录查找字节码类文件,并创建加载对应的class对象


    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
      try{
          byte[] b = loadClassFromFile(name);
          Class<?> c = defineClass(name,b,0,b.length);
          return c;
      }catch(IOException ex){
          throw new ClassNotFoundException(ex.getMessage());
      }
    }

    byte[] loadClassFromFile(String name) throws IOException{
        String fileName = name.replace('.', File.separatorChar)+".class";
        String filePath = this.customPath+fileName;
        try(InputStream inputStream = new FileInputStream(filePath);
            ByteArrayOutputStream baos = new ByteArrayOutputStream()){
            int nextValue;
            while((nextValue=inputStream.read())!=-1){
                baos.write(nextValue);
            }
            return baos.toByteArray();
        }
    }
}

 

相关新闻
热点
视频
投票
查看结果
Tags

站点地图 在线访客: 今日访问量: 昨日访问量: 总访问量:

© 2025 个人网站 版权所有

备案号:苏ICP备2024108837号

苏公网安备32011302322151号