类加载器以及SPI

目录:           申明           JVM类加载以及SPI类的生命周期:1.加载2.验证类加载器以及双亲委派模型SPI (service provider interface)3.准备4.解析5.初始化阶段申明本文很多的内容都是作者通过阅读《深入理解Java虚拟机[JVM高级特性与最佳实践](周志明)》这本书学习到的。如果需要关于类...
摘要由CSDN通过智能技术生成

目录:

           申明

           JVM类加载以及SPI

类的生命周期:

1.加载

2.验证

类加载器以及双亲委派模型

SPI (service provider interface)

3.准备

4.解析

5.初始化阶段

申明

本文很多的内容都是作者通过阅读《深入理解Java虚拟机[JVM高级特性与最佳实践](周志明)》这本书学习到的。如果需要关于类加载更加详细的细节信息,请自行去阅读JVM 相关书籍

JVM类加载以及SPI

类的生命周期:

 

 

说明:只有加载阶段用户可以通过自定义类加载器参与,别的阶段都是虚拟机自己主导的

1.加载

  1. 通过类的全限定名获取描述此类的二进制字节流(获取方式任意—这是一个开放式规范 比如:动态代理,网络传输,zip包中读取比如jar,war。从数据库中读取……)
  2. 将字节流所代表的静态存储结构保存为方法区的运行时数据结构(1.8以后存在meta space,1.7 开始 类的静态量以及 常量 都存在 head 区)
  3. 在java head 创建一个这个类的java.lang.Class 对象,作为访问 方法区(1.8 meta space )的入口

 

说明:后面的所有加载操作我都统称loading

2.验证

  • 格式验证:验证字节流是否是符合class文件格式规范,是否能被当前虚拟机处理
  1.   是否以魔数0xCAFEBABE开头(这个是jvm 验证的一个标准 )
  2.   主次版本号是否在当前虚拟机的处理范围(1.7的代码,你用1.6 jvm 编译肯定编译不了,这个就是验证这类版本号的)
  3.   常量池的常量中是否有不被支持的常量类型(检查常量的tag标志)
  4.   Class文件中各部分及文件本身是否有被删除或附加其他信息
  5.   ……….
  • 元数据验证:对字节码描述信息进行语意解析,以保证其描述的信息符合java语言规范要求
  1.   这个类是否有父类(除了Object所有类又应该有父类)
  2.   这个类是否继承了不允许被继承的类(比如final 修饰的类就不能被继承)
  3.   如果这个类不是abstract 类,是否实现了父类或接口中要求实现的方法
  4.   ……..

提示:所有类最终父类都是Object

  • 字节码验证:这是最复杂的一个阶段,主要进行数据流和控制流分析。该阶段将会对类的方法体进行分析,以保证被校验类的方法在运行时不会做出危害虚拟机安全的行为
  1.   保证方法体中的类型转换是有效的,比如把一个父类赋值给子类,或则把一个类赋值给一个毫无关系的类,这样的操作就是不合法的
  2.   保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,而不会出现像:在操作数栈放一个int数据,使用时却按照long来加载进入局部变量表中
  3.   ……
  • 符号引用验证:这个阶段的校验发生在虚拟机将符号引用转换为直接引用的时候(也就是在解析阶段的时候)
  1.   符号引用中通过字符串描述的全限定名是否能找到对应的类
  2.   在指定类中是否存在符合方法的符号的字段描述符以及简单的名称描述的方法和字段
  3.   引用中的类、字段、方法的访问性(public,private…)是否能被当前类访问

 

类加载器以及双亲委派模型

上面的加载阶段的第一步,通过类的全限定名获取描述此类的二进制字节流。这个动作,就是对用户开放的一个动作,在这个阶段java 平台开发者 可以自定义自己的类加载器,方法是有很多种。

         这里说一下 双亲委派模型 以及下面的SPI 规范的一种方式

 

双亲委派模型

 

  • 首先 从java 虚拟机角度来说分为两种类加载器:
  1.   启动类加载器(Bootstrap ClassPoader)这个类加载器由C++实现,虚拟机的一部分
  2.   其他所有的由java实现的类加载器

 

  • 从java 开发人员的角度来看 类加载器分得更细一些,大多数时候我们会使用到系统提供的三种类加载器:
  1.   启动类加载器(Bootstrap ClassLoader)他负责加载<JAVA_HOME>/lib 目录中的,或则被-Xbootclasspath参数所指定的路径中被虚拟机识别的的jar(比如rt.jar,名字不符合的及时放在lib 也不会被加载的) 到虚拟机的内存中。

说明:启动类加载器无法被java程序直接引用

  1.   扩展类加载器(Extension ClassLoader)这个由sun.misc.Launcher$ExtClassLoader 实现,它负责加载<JAVA_HOME>/lib/ext 下面的jar 。或则被java.ext.dirs 系统变量所指定的路径中的所有类库
  2.   应用类加载器(Application CLassLoader)这个sun.misc.Launcher$AppssLoader

实现,这个类的实例是ClassLoader.getSystemClassLoader()的返回值,所以也叫它系统类加载器,他负责加载classpath 下面的所有类,如果程序中没有自定义的类加载器,一般就是使用的这个类加载器了

  1. 模型图:

<

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
类加载器ServiceLoader是Java的一个工具类,用于加载和实例化服务提供者接口的实现类。它的作用是在运行时动态地加载实现了某个接口的类,并创建其实例。ServiceLoader使用了线程上下文类加载器来加载类,这样可以解决父类加载器无法加载子类加载器加载的类的问题。\[1\]\[3\] 具体来说,ServiceLoader会使用当前类的类加载器来加载其他类,如果一个类引用了另一个类,那么它的类加载器就会去加载被引用的类(前提是被引用的类尚未加载)\[2\]。而在某些情况下,高层提供了统一的接口让低层去实现,并且需要在高层加载或实例化底层的类时,就需要通过线程上下文类加载器来帮助高层的类加载器找到并加载该类\[3\]。 虽然我们可以直接使用getClassLoader获取系统类加载器去加载对应的类,但是使用上下文类加载器更加方便,因为它可以在任何代码执行的线程随时取出来使用\[3\]。所以在使用ServiceLoader时,我们可以使用线程上下文类加载器来加载服务提供者接口的实现类。 #### 引用[.reference_title] - *1* [打破双亲委派之SPI、线程上下文类加载器、ServiceLoader](https://blog.csdn.net/weixin_45902285/article/details/121757550)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【JVM类加载】线程上下文的类加载器及使用模式ServiceLoader(服务加载器)在SPI的重要作用分析...](https://blog.csdn.net/qq_42261668/article/details/102607997)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值