类加载器与双亲委派机制

发布时间:2024年01月23日

类加载器

Class Loader是通过loadClass加载类,有如下几步:

  • 加载:从硬盘上读取字节码文件,使用到时才会加载;
  • 验证:校验字节码文件的正确性;
  • 准备:给类的静态变量分配内存,并赋予默认值。注意,这里的默认值不是在代码里变量的初始值;
  • 解析:将符号引用替换为直接引用,该阶段会把一些静态方法替换为指向数据所存内存的指针或句柄等,这时所谓的静态链接过程,动态链接时在程序运行期间完成的将符号引用替换为直接引用;
  • 初始化:对静态变量初始化指定的值,此时才进行代码中的赋值操作;
    ????????类被加载到方法区后包含运行时常量池、类型信息、字段信息、方法信息、类加载器的引用、对应class实例的引用等信息。
    ????????对应class实例的引用:在类加载到方法区后,会创建一个对应的Class类型的对象放到堆中,作为开发人员访问方法区中类定义的入口和切入点。
    ????????注意:jar包或war包不是一次性加载所有类,而是在使用的时候加载。

类加载器和双亲委派机制

Java中有如下几种类加载器:

  • 引导类加载器:负责加载JRE的lib目录下的核心类库,如rt.jar、charsets.jar等
  • 扩展类加载器:负责加载lib目录下ext目录中的Jar包
  • 应用程序类加载器:即加载ClassPath目录下的类,即加载我们应用程序相关的类
  • 自定义加载器:负责加载自定义路径下的类包

什么是双亲委派机制

????????双亲委派机制是Java中的一种类加载机制。双亲委派机制是当加载一个类时,先由父类加载,父类加载不到时再由子类加载。
????????这种机制的好处是避免了类的重复加载,提高了类加载的效率和安全性。同时,它也为Java提供了一种扩展机制,允许开发人员自定义类加载器,实现特定的加载策略。

为什么要设计双亲委派机制?

  • 沙箱安全机制:如自己写的java.lang.String.class类不会被加载,这样可以防止核心API库被随意篡改。
  • 避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证被加载类的唯一性
    在这里插入图片描述
    tomcat的几个主要类加载器:
  • commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;
  • catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
  • sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
  • WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见,比如加载war包里相关的类,每个war包应用都有自己的WebappClassLoader,实现相互隔离,比如不同war包应用引入了不同的spring版本,这样实现就能加载各自的spring版本;

????????从途中的委派关系中可以看出:
CommonClassLoader能加载的类都可以被CatalinaClassLoader和SharedClassLoader使用,从而实现了公有类库的共用,而CatalinaClassLoader和SharedClassLoader自己能加载的类则与对方相互隔离。
WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。
而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的就是为了被丢弃;当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的热加载功能。
????????每个webappClassLoader加载自己目录下的class文件,不会传递给父类加载器,打破了双亲委派机制。

文章来源:https://blog.csdn.net/ariestse9/article/details/135695390
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。