JVM类加载机制
SUN JVM中的ClassLoader采用的是双亲委派加载模式,类加载器之间是树状父子关系。加载类时首先检查父加载器能否加载,只有父加载器不能加载的情况下,才会自己加载。这样的好处是可以防止Java的核心类被恶意程序覆盖。
JVM内置的类加载器有3个:
1. Bootstrap ClassLoader:
这个加载器是native代码实现的,主要负责加载核心的Java库rt.jar中的类。
2. Extensions ClassLoader:
负责载入标准扩展目录中的类,例如JVM的扩展目录是/jdk/jre/lib/ext。
3. Application ClassLoader:
默认的类加载器,加载CLASSPATH路径中的类。
Tomcat类加载机制
Tomcat中除了使用JVM的委派加载模型,还使用了自己的加载方式,称之为servlet加载模型。Tomcat8.0中WebappClassLoader的核心方法loadClass:
1. 首先检查本地缓存是否存在(findLoadedClass0/ findLoadedClass)。
2. 委托系统加载器进行加载。
3. 如果设置delegate,委托给delegate父加载器加载,不成功再从本地加载。
4. 如果没有设置delegate,先从本地进行加载,不成功委托父加载器加载。
Tomcat中默认使用的是servlet加载方式,即先检查本地是否能够加载,如果不能再委托给父加载器。
Web中的jar包搜索顺序:
1. Java目录。
2. Web应用:WEB-INF\classes, WEB-INF\lib下的包。
3. Tomcat\lib下的包。
因此,如果在Web中共享jar包的话,只能将jar文件放在Tomcat\lib,Web应用WEB-INF\lib中该jar包必须要删除,否则,不同Web应用使用不同加载器进行加载,会造成ClassCastException。