ClassLoader功能:将Class加载到JVM中、审查每个类应该由谁加载,采用父优先的登记加载机制、将Class字节码重新解析成JVM统一要求的对象格式。
1、整个JVM平台提供3层ClassLoader,这3层ClassLoader可以分为俩种类型,可以理解为为接待室服务的接待室和为会员服务的接待室。
1)BootstrapClassLoader:就是接待室服务自身的,主要加载JVM自身工作需要的类,完全是由JVM自己控制,这个ClassLoader不遵循类加载规则,仅仅是一个类类的加载工具而已,没有更高一级的父加载器,也没有子加载器
2)ExtClassLoader:该加载器是JVM自身一部分,但他不是JVM亲自实现的,他加载那些既不是JVM内部的,也和普通的外部会员不同的类,服务的特定目标在System.getProperty(“java.ext.dirs”)目录下
3)AppClassLoader:该类加载器专门用于接待会员服务的,父类ExtClassLoader,在System.getProperty(“java.class.path”)目录下的类都能被这个类加载
4)从源码中可以看出2、 3加载器都属于Launcher类中的静态内部类,而且他们都继承URLClassLoader类,System.getProperty(“java.ext.dirs”)目录下是由ExtClassLoader加载,其他都是由AppClassLoader来加载。
5)JVM加载class文件到内存中的俩种方式:
隐式加载:就是不通过代码里调用ClassLoader来加载需要的类,而是JVM需要应用某个类的时候,发现该类不在内存中,则自动加载到内存中。
显示加载:与隐式加载相反,是我们在代码中调用ClassLoader类来加载。
2、加载class文件步骤
1)第一个阶段找到.class文件并且将其包含的字节码加载到内存中。
2)第二阶段分为三个步骤:分别是字节码验证、Class类数据结构分析、内存分配、符号表的链接。
3)第三个阶端对类中静态属性和初始化赋值以及执行静态块。
3、加载类常见的错误
1)ClassNotFoundException:原因是当JVM要加载指定的文件的字节码都内存中时,找不到该文件,解决的方式是检查当前的classpath目录下是否有指定的文件,如果不值到当前的classpath路径,可以通过this.getClass().getClassLoader().getResource(“”).toString();
2)NotClassFoundException:JVM找不到给文件,解决方式是确保每个类引用类都在当前的classpath下面。
3)UnsatisfiedLinkError:通常是在啊JVM启动时,如果不小心将在JVM中的耨个lib删除了,可能会报这么错。
4)ClassCastExcep.tion:程序中在出现强制类型转换时,可能会出现,解决方式:显示指明容器所包含的对象类型或者先通过instanceof检查。
5)ExceptionInInitializerError:如果初始化器爆出一些Exception,但该异常不是error也不是他的某个子类。
4、加载机制:
1)WebAppClassLoader加载机制:
a)首先检查在WebAppClassLoader中是否已被加载过,如果请求的类以前在WebappClassLoader加载的,那么肯定在WebappClassLoader的缓存容器resourceEntries中,如果不在,则继续检查在JVM虚拟机是否已经加载过,也就是调用ClassLoader的findLoadedClass方法;
b)如果前俩个缓存中都没有,则先调用SystemClassLoader加载请求的类,SystemClassLoader在这里是AppClassLoader;
c)检查请求的类是否在packageTriggers定义的包名下,如果在则通过StandardClassLoader类加载;如果仍然没有找到,则由WebappClassLoader加载,其将在应用的WEB-INF/classes目录下查请求的类文件的字节码,找到后创建一个ResourceEntry对象保持类的元信息,并将其保持在WebappClassLoader的resourceEntries容器,便于下次查找,接着将调用defineClass方法生成请求Class对象并返回给InstanceManager来创建实例。
2)Servlet容器启动过程:ContextConfig的初始化init方法主要完成的工作:
a)创建用于解析XML配置文件的contextDigester对象
b)读取默认的context.xml配置文件,如果存在则解析它
c)读取默认的Host配置文件,如果存在则解析它
d)读取默认的Context自身的配置文件,若存在则解析
e)设置Context的DocBase
3)ContextConfig的init方法完成后,Context容器会执行startInternal方法,该方法启动逻辑主要包括以下部分:
a)创建读取资源文件的对象
b)创建ClassLoader对象
c)设置应用的工作目录
d)启动相关的辅助类,如logger、realm、resource等
e)修改启动状态,通知感兴趣的观察者(Web应用的配置)
f)子容器的初始化。
g)获取ServletContext并设置必要的参数
h)初始化“load on startup”的Servlet。