深入分析java web 的ClassLoader工作机制(一)

一、ClassLoader简介:


ClassLoader是类加载器,

责任1.将Class加载到JVM中,

责任2.审查每个类应该由谁加载,

责任3.将Class字节码重新解析成JVM统一要求的对象格式。


ClassLoader它是一个父优先的等级加载机制,下面介绍几个它的常用方法:


defineClass方法用来将byte字节流解析成JVM能够识别的Class对象,有了这个方法意味着我们不仅仅可以通过class文件实例化对象,还可以通过其他方式如我们通过网络接收到一个类的字节码,拿这个字节码流直接创建类的Class对象形式是实例化对象。

注意,如果直接调用这个方法生成类的Class对象,这个类的class对象还没有resolve,这个resolve将会在这个对象真正实例化时才进行。


difineClass通常是和findClass方法一起使用的,我们通过直接覆盖ClassLoader父类的findClass方法来实现类的加载规则,从而取得要加载类的字节码。然后调用difineClass方法生成类的Class对象,如果你想在类被加载到JVM中时就被链接(Link),那么可以接着调用另外一个resolveClass方法,当然你也可以选择让JVM来解决什么时候才链接这个类。


如果你不想重新定义加载类的规则,也没有复杂的处理逻辑,只想在运行时能够加载自己指定的一个类而已,那么你可以用this.getClass().getClassLoader().loadClass("class")调用ClassLoader(是个抽象类)的loadClass方法以获取这个类的Class对象。


二、ClassLoader的等级加载机制


ClassLoader采用上级委托机制,整个JVM中提供三个ClassLoader类,这三个ClassLoader可以分为俩种类型:


1、Bootstrap ClassLoader:这个ClassLoader主要加载JVM自己工作需要的类,这个Bootstrap ClassLoader完全是JVM自己控制的,需要加载那个类,怎么加载都由JVM自己控制,别人也访问不到这个类。


2、ExtClassLoader:这个类是JVM自己的一部分。


3、AppClassLoader:它的父类是ExtClassLoader。


JVM加载class文件到内存由俩种方式。

    隐式加载:所谓隐式加载就是不通过在代码里调用ClassLoader来加载需要的类,而是通过JVM来自动加载需要的类到内存的方式。例如,当我们在类中继承或者引用某个类,JVM在解析当前这个类时发现引用的类不再内存中,那么就会自动将这些类加载到内存中。

    显式加载:显式加载就是我们在代码中通过调用ClassLoader类来加载一个类的方式,例如,调用this.getClass.getClassLoader().loadClass()或者Class.forName(),或者我们自己实现的ClassLoader的findClass()方法等。


三、如何加载class文件


1、加载字节码到内存


抽象类ClassLoader并没有定义如何去加载,如何去找到指定类并且把它的字节码加载到内存需要它的子类中去实现,也就是实现findClass()方法。我们看一下子类URLClassLoader是如何实现findClass()的,在URLClassLoader中通过一个URLClassPath类帮助取得要加载的class文件字节流,而这个URLClassPath定义了到哪里去找这个class文件,如果找到了这个class文件,再读取它的byte字节流通过调用defineClass()方法来创建类对象。


猜你喜欢

转载自blog.csdn.net/darrensty/article/details/78680130