前面的动态代理学完了,以后在学习Spring的时候会用到这些动态代理的知识和原理,像目标对象,增强这两个术语,会经常听到。学习动态代理,就是学习JDK中反射包下的一个Proxy类,具体来说,我们只是学习newProxyInstance(ClassLoader, interfaces, hander)这个方法。这篇开始来学习下,加载器,我们在学习获取动态代理,第一个要准备的参数就是,类加载器,通过这篇的学习,稍微对类加载器有入门的了解。

来源:凯哥Java(kaigejava)

什么是类加载器(作用)

就是把计算机本地磁盘上的.class文件加载进JVM内存中方法区,变成Class对象,实现这个过程的对象就是类加载器,这个类加载器本身也是一个类。

如何得到类加载器

前面我们学习动态代理的时候,是通过当前类来获取类加载器,就是下面这行代码。

ClassLoader loader = this.getClass().getClassLoader();

这个getClassLoader()方法是在Class类中定义的方法。

类加载器的分类

类加载器有三个分类,以下三类分工明确,负责不同的类加载。

引导类加载器

这个分类主要是类库加载,例如jre下面的lib文件夹中的rt.jar中类加载进JVM内存。

扩展类加载器

这部分就是把扩展的类库加载到内存,例如jre下面的ext文件夹下的全部文件,ext就是英文扩展单词的前缀缩写。

系统类加载器

这分类就是加载一些应用下的类,例如我们写一个web项目,我们使用到很多其他第三方的jar包,这些类就是系统类加载器来完成加载。还有我们自己写的代码文件,也是系统类加载器完成这操作。

这三个分类的关系是,系统类加载器的上层是扩展类加载器,扩展类加载器的上层是引导类加载器,引导类加载器是老大,没有上层。


类加载器的委托机制

由于上面三个类加载器分类的关系,产生了一个概念,叫类加载器的委托机制。先来看看下面这个过程,然后解释什么是委托机制。

一开始,我们在代码中写这行代码new A(); 由于A类可能是JDK自带,也可能是程序员自己写的,这个类在加载进内存需要经历下面这个过程。

1) 系统类加载器发现自己要加载A类,因为这是在应用下的代码,理应系统类加载器去处理加载。

2) 系统类加载器,根本不看这个A类是不是在自己管辖范围,直接通知扩展类加载器,想让扩展加载器去加载A类。

3) 扩展加载类也不管,直接通知引导加载类,想让引导加载类去执行加载。

4) 引导加载类发现这个A类是rt.jar中的类,然后就加载到JVM内存的方法区,把这个Class对象返回给了扩展,然后扩展把这个对象Class对象返回给系统加载类,加载过程结束。

5) 如果引导加载器发现A类不是自己管辖范围,返回null给扩展。

6) 扩展类加载器发现上层返回null, 只好扩展去自己管辖范围查找,查找到了,就加载进入内存,返回对应class对象给系统加载器,加载过程结束。

7) 如果扩展器没有找到A类,就返回null给系统类加载器。

8) 系统类加载器发现上层返回null,只好去自己管辖范围查找A类,找到了就加载进JVM内存,返回class对象,加载过程结束。

9) 如果系统类也找不到这个A类,抛出异常,ClassNotFoundException

这个过程就是委托机制,所有加载任务都优先交给自己的上层去完成,上层完成不了然后才自己处理,这样就包装了类加载的安全,不会同时存在,三个类型加载器同时加载一个类的情况。

在实际的类解析过程中,类的加载还是要看线程,每一个线程就有自己的类加载器。所以本篇的类加载器的基础,有助于我们以后学习多线程并发和JVM这块的知识点。

l联系凯哥:凯哥Java(kaigejava)或凯哥个人博客:www.kaigejava.com(凯哥个人博客可以发即时消息给凯哥哦~)

Tomcat中的类加载器

简单来了解下Tomcat中的类加载器,在Tomcat中有两种类加载器。

1) 服务器类加载器,负责加载tomcat下${CATALINA_HOME}\lib下的类,也就是tomcat安装目录下lib文件夹中的类。

2) 应用类加载器,这个主要加载当前web项目下\WEB-INF\lib \WEB-INF\classes就是我们程序员代码编译之后文件在\WEB-INF\classes,一些第三方jar包在\WEB-INF\lib

说一下这种类加载器和前面知道的三个类加载器的区别和关系。在Tomcat下两种类加载器都排下上面系统类加载器的下面,这两个的上层都是系统类加载器。在Tomcat中的两种类加载器有一个共同特性:先自己动手,然后去委托。通过前面的委托机制的学习,应该知道这句话的含义。Tomcat中两种类加载器会自己一开始就去自己管辖范围查找和加载类,如果没有找到才去委托给系统类加载器。