类加载器与双亲委派机制

1.什么是类加载器

就是将我们的字节码(class文件)读取到JVM内存中。

2.读取class文件来源

1:本地磁盘文件 java代码变为的class文件

2:通过网络下载的class文件

3:War、jar 解压的class文件

4:从专门的数据库中读取的class文件

5:使用 java cglib、动态代理生成的代理类class文件

3.类加载的分类

1.启动(Bootstrap)类加载器:加载JVM自身工作需要的类,它由JVM自己实现。它会加载$JAVA_HOME/jre/lib下的文件 底层是C语言实现

2.扩展(Extension)类加载器:它是JVM的一部分,由sun.misc.LauncherExtClassLoader实现,他会加载ExtClassLoader实现,他会加载ExtClassLoader实现,他会加载JAVA_HOME/jre/lib/ext目录中的文件(或由System.getProperty(“java.ext.dirs”)所指定的文件)。 底层是Java实现

3.(应用)AppClassLoader 类加载器:应用类加载器,我们工作中接触最多的也是这个类加载器,它由sun.misc.Launcher$AppClassLoader实现。他加载我们工程目录classpath下的class及jar包  底层是java实现

4.自定义类加载器: 也就是用户自己定义的类加载器

 

类加载器执行顺序图:

 

 类加载器分类职能图:

 

4.那些操作会触发类加载操作

类的主动使用:

1. 调用类的静态方法

2. invokeStatic   调用静态方法

3. Main

4. New

5. Class.formname

6. 子类初始化一定会初始化父类 初始化一个类,那么一定会触发类加载器 但是类加载器加载了该类,但是该类不一定初始化。

5.类加载器的双亲委派机制

首先在我们类加载器分为四种 自定义类加载器、应用类加载器、扩展类加载器、启动类加载器。

当一个类加载器收到请求之后,首先会依次向上查找到最顶层类加载器(启动类加载器),依次向下加载class文件,如果已经加载到class文件,子加载器不会加继续加载该class文件。

6.双亲委派机制的好处

依次向上查找最顶端启动类加载器读取class文件,只要启动类加载器读取成功之后,以后不会再扩展、应用类加载器读取。

目的:就是为了防御开发者定义的类与jdk定义源码类产生冲突问题,保证该类在内存中的唯一性。

7.ClassLoader源码解读

 

 8.默认当前线程关联的是应用类加载器(Launcher类)

 9.如何破坏双亲委派原则

双亲委派代码在loadclass方法中,只需要绕开loadclass方法即可。

1:自定义类加载器  重写loadclass方法。

2:Spi机制绕开loadclass方法,当前线程设置关联类加载器。

Spi机制绕开loadclass方法,核心先找到当前类的类加载器目录下是否有该Spi机制对应的配置文件,如果没有的情况下则不会进行初始化该类,会报错。

10.SPI机制介绍

Spi机制加载第三方扩展的Jar包类初始化,对我们接口的子类实现初始化。

例如:java-JDBC 使用mysql驱动Jar包(初始化Driver类)、dubbo中RPC调用的时候。

SPI命名规范:

文件夹命名:存在在项目中 Resoucres 新建META-INF.services

文件命名:必须是接口类的完全限定名称(需要初始化类的接口名称)

 

 

 

JVM 虚拟机内存空间图:

 

posted @ 2021-03-03 11:38  明天,你好啊  阅读(341)  评论(0编辑  收藏  举报