ClassLoader作用

Java程序在运行的时候,JVM通过类加载机制(ClassLoader)把class文件加载到内存中,只有class文件被载入内存,才能被其他class引用,使程序正确运行起来.

ClassLoader的分类

Java中的ClassLoader有三种:Bootstrap ClassLoader 、Extension ClassLoader、App ClassLoader。

1. Bootstrap ClassLoader

由C++写的,由JVM启动.

启动类加载器,负责加载java基础类,对应的文件是%JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等

2.Extension ClassLoader

Java类,继承自URLClassLoader 扩展类加载器,

对应的文件是 %JRE_HOME/lib/ext 目录下的jar和class等

3.App ClassLoader

Java类,继承自URLClassLoader 系统类加载器,

对应的文件是应用程序classpath目录下的所有jar和class等

java中class的加载顺序

$java_home/lib 目录下的java核心api
$java_home/lib/ext 目录下的java扩展jar包
java -classpath/-Djava.class.path所指的目录下的类与jar包
$CATALINA_HOME/common目录下按照文件夹的顺序从上往下依次加载
$CATALINA_HOME/server目录下按照文件夹的顺序从上往下依次加载
$CATALINA_BASE/shared目录下按照文件夹的顺序从上往下依次加载
我们的项目路径/WEB-INF/classes下的class文件
我们的项目路径/WEB-INF/lib下的jar文件

三、ClassLoader的加载机制

Java的加载机制是双亲委派机制来加载类,

为什么要使用这种方式?这个是为了保证 如果加载的类是一个系统类,那么会优先由Bootstrap ClassLoader 、Extension ClassLoader先去加载,而不是使用我们自定义的ClassLoader去加载,保证系统的安全!

双亲委派机制

通俗点讲,双亲可以浅显理解为父类,当.class文件将要被加载到JVM中时,会先交由AppClassLoader去加载,这时目前的ClassLoader不会去加载,而是一直向上,让父类去加载。

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。
每一个层次的类加载器都是如此。因此,所有的加载请求最终都应该传送到顶层的启动类加载器中。
只有当父加载器反馈自己无法完成这个加载请求时(搜索范围中没有找到所需的类),子加载器才会尝试自己去加载。

java classload javaclassloader类_jvm

四、自定义ClassLoader

1、为什么要自定义ClassLoader

因为系统的ClassLoader只会加载指定目录下的class文件,如果你想加载自己的class文件,那么就可以自定义一个ClassLoader.

而且我们可以根据自己的需求,对class文件进行加密和解密。

2.如何自定义ClassLoader

2.1新建一个类继承自java.lang.ClassLoader,重写它的findClass方法。

2.2将class字节码数组转换为Class类的实例

2.3调用loadClass方法即可