1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-16 18:10:13 +08:00

Update 类加载器.md

This commit is contained in:
guide 2021-08-07 15:18:25 +08:00
parent 3e91372140
commit ab0874f0db

View File

@ -1,42 +1,26 @@
<!-- TOC -->
- [回顾一下类加载过程](#回顾一下类加载过程)
- [类加载器总结](#类加载器总结)
- [双亲委派模型](#双亲委派模型)
- [双亲委派模型介绍](#双亲委派模型介绍)
- [双亲委派模型实现源码分析](#双亲委派模型实现源码分析)
- [双亲委派模型的好处](#双亲委派模型的好处)
- [如果我们不想要双亲委派模型怎么办?](#如果我们不想要双亲委派模型怎么办)
- [自定义类加载器](#自定义类加载器)
- [推荐](#推荐)
<!-- /TOC -->
> 公众号JavaGuide 后台回复关键字“1”免费获取JavaGuide配套的Java工程师必备学习资源(文末有公众号二维码)。
## 回顾一下类加载过程 ## 回顾一下类加载过程
类加载过程:**加载->连接->初始化**。连接过程又可分为三步:**验证->准备->解析**。 类加载过程:**加载->连接->初始化**。连接过程又可分为三步:**验证->准备->解析**。
![类加载过程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/类加载过程.png) ![类加载过程](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/类加载过程.png)
一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的 `loadClass()` 方法)。数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。 一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去自定义类加载器去控制字节流的获取方式(重写一个类加载器的 `loadClass()` 方法)。数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。
所有的类都由类加载器加载,加载的作用就是将 .class文件加载到内存。 所有的类都由类加载器加载,加载的作用就是将 `.class`文件加载到内存。
## 类加载器总结 ## 类加载器总结
JVM 中内置了三个重要的 ClassLoader除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自`java.lang.ClassLoader` JVM 中内置了三个重要的 ClassLoader除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自`java.lang.ClassLoader`
1. **BootstrapClassLoader(启动类加载器)** 最顶层的加载类由C++实现,负责加载 `%JAVA_HOME%/lib`目录下的jar包和类或者`-Xbootclasspath`参数指定的路径中的所有类。 1. **BootstrapClassLoader(启动类加载器)** :最顶层的加载类,由 C++实现,负责加载 `%JAVA_HOME%/lib`目录下的 jar 包和类或者被 `-Xbootclasspath`参数指定的路径中的所有类。
2. **ExtensionClassLoader(扩展类加载器)** :主要负责加载目录 `%JRE_HOME%/lib/ext` 目录下的jar包和类或被 `java.ext.dirs` 系统变量所指定的路径下的jar包。 2. **ExtensionClassLoader(扩展类加载器)** :主要负责加载 `%JRE_HOME%/lib/ext` 目录下的 jar 包和类,或被 `java.ext.dirs` 系统变量所指定的路径下的 jar 包。
3. **AppClassLoader(应用程序类加载器)** :面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。 3. **AppClassLoader(应用程序类加载器)** :面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。
## 双亲委派模型 ## 双亲委派模型
### 双亲委派模型介绍 ### 双亲委派模型介绍
每一个类都有一个对应它的类加载器。系统中的 ClassLoder 在协同工作的时候会默认使用 **双亲委派模型** 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派父类加载器的 `loadClass()` 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 `BootstrapClassLoader` 中。当父类加载器无法处理时才由自己来处理。当父类加载器为null时会使用启动类加载器 `BootstrapClassLoader` 作为父类加载器。 每一个类都有一个对应它的类加载器。系统中的 ClassLoader 在协同工作的时候会默认使用 **双亲委派模型** 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派父类加载器的 `loadClass()` 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 `BootstrapClassLoader` 中。当父类加载器无法处理时,才由自己来处理。当父类加载器为 null 时,会使用启动类加载器 `BootstrapClassLoader` 作为父类加载器。
![ClassLoader](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/classloader_WPS图片.png) ![ClassLoader](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/classloader_WPS图片.png)
@ -129,6 +113,3 @@ protected Class<?> loadClass(String name, boolean resolve)
- <https://blog.csdn.net/xyang81/article/details/7292380> - <https://blog.csdn.net/xyang81/article/details/7292380>
- <https://juejin.im/post/5c04892351882516e70dcc9b> - <https://juejin.im/post/5c04892351882516e70dcc9b>
- <http://gityuan.com/2016/01/24/java-classloader/> - <http://gityuan.com/2016/01/24/java-classloader/>