Java虚拟机:类加载过程,类加载器

类加载过程

Java虚拟机类加载的五个过程:①加载 ②验证 ③准备 ④解析 ⑤初始化
①加载:获取类的二进制字节流—>转化为方法区的运行时数据结构—>在堆内生成java.lang.Class对象
②验证:验证字节流是否符合规定(文件格式验证,元数据验证,字节码验证,符号引用验证)
③准备:为静态变量分配内存—>初始化变量
④解析:将符号引用替换为直接引用
⑤初始化:初始化变量

在这里插入图片描述

类加载器

Java虚拟机设计团队有意把类加载阶段中的 “通过一个类的全限定名来获取描述该类的二进制字节流” 这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需的类。实现这个动作的代码被称为 “类加载器”

类与类加载器

每一个类加载器,都有一个独立的类名称空间。通俗的说:比较两个类是否“相等”,只有这两个是由 同一个类加载器加载的前提下才有意义,否则即使这两个类来源于同一个Class文件,被同一个Java虚拟机加载,只要加载它们的类加载器不同,那这两个类就必定不相等。

双亲委派模型
①启动类加载器
②扩展类加载器:Java系统类库的扩展机制
③应用程序类加载器:加载用户路径(ClassPath)上所有的类库

在这里插入图片描述
双亲委派模型的工作过程:如果一个类加载器收到了类加载的请求,首先不会尝试自己加载这个类,而是把这个请求 委派给父类加载器去完成,每一层的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中;只有父类加载器反馈自己 无法完成这个加载请求时, 子类加载器才会自己尝试去完成加载

使用双亲委派模型的好处是:例如类 java.lang.Object,无论哪一个类加载器加载这个类,最终都委派到启动类加载器进行加载,因此Object类在程序的各种类加载器环境中 都能够保证是同一个类

Tomcat 的类加载器为何需要打破双亲委派模型

Tomcat是什么? 是web容器
web容器可能需要部署两个应用程序, 不同的应用程序可能会依赖 同一个第三方类库的不同版本

如果使用 默认的类加载器机制 ,那么是无法加载两个相同类库的不同版本的,默认的累加器是不管你是什么版本的, 只在乎全限定类名,并且只有一份

web容器也有自己依赖的类库,不能于应用程序的类库混淆。基于安全考虑,应该让容器的类库和程序的类库隔离开来。
Tomcat有四个加载器:①CommonClassLoader、②CatalinaClassLoader、③SharedClassLoader、④WebappClassLoader

①CommonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;
②CatalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
③SharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
④WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见;

Tomcat破坏双亲委派机制体现在:每个webappClassLoader 加载自己的目录下的class文件 不会传递给父类加载器
如果tomcat 的 Common ClassLoader 想加载 WebApp ClassLoader 中的类,该怎么办?

使用线程上下文类加载器实现,使用线程上下文加载器,可以让父类加载器请求子类加载器去完成类加载的动作。

参考:

《深入理解Java虚拟机,第三版》周志明著
深入理解 Tomcat(四)Tomcat 类加载器之为何违背双亲委派模型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值