jvm类加载和tomcat类加载机制

应用程序在启动的时候需要启动虚拟机进行加载class文件到内存中。然后等待程序的调用。那么有时候我们的程序回报一个错误:

ClassNotFoundException异常。什么情况下会报这个异常呢?也许你会说jvm找不到类。但是jvm它是怎么进行加载的呢?加载的机制是怎么样的?

jvm采用委托上级的加载机制加载类。那么jvm的加载器自上而下四个:

BootStraptClassLoader:虚拟机启动时加载虚拟机内部的class文件。引导加载器

ExtClassLoader:扩展类加载器加载jdk目录下ext目录里面的jar。如图:扩展类加载器

applicationClassLoader:应用加载器,加载应用classpath目录下的文件。也就是应用代码编译后的文件

customerClassLoader  用户自定义加载器。最后是用户自定义类加载器

整个加载过程采用委托上层加载器加载。自上而下,在各自的加载区域加载文件,如果到customerClassLoader仍

找不到文件,就会爆出CllassNotFourndException 异常,退出程序。

TOMCAT的加载机制:下面是tomcat的目录

Bootstramp:  加载虚拟机所需的jar.以及jdk中标准的扩展类jre/lib/ext目录下面

System:   加载tomcat启动文件catalina.bat文件中指定的类

Common:加载tomcat的lib包下面的类。

最后加载应用加载器首先加载CLASSPATH  ,其次加载 WEB-INFO/lib目录下的jar文件

当应用需要到某个类时,则会按照下面的顺序进行类加载

1、使用bootstrap引导类加载器加载

2、使用system系统类加载器加载

3、使用应用类加载器在WEB-INF/classes中加载

4、使用应用类加载器在WEB-INF/lib中加载

5、使用common类加载器在CATALINA_HOME/lib中加载

问题扩展

  通过对上面tomcat类加载机制的理解,就不难明白 为什么java文件放在Eclipse中的src文件夹下会优先jar包中的class?

  这是因为Eclipse中的src文件夹中的文件java以及webContent中的JSP都会在tomcat启动时,被编译成class文件放在 WEB-INF/class中。

  而Eclipse外部引用的jar包,则相当于放在 WEB-INF/lib 中。

  因此肯定是 java文件或者JSP文件编译出的class优先加载

  通过这样,我们就可以简单的把java文件放置在src文件夹中,通过对该java文件的修改以及调试,便于学习拥有源码java文件、却没有打包成xxx-source的jar包。

另外呢,开发者也会因为粗心而犯下面的错误。

  在 CATALINA_HOME/lib 以及 WEB-INF/lib 中放置了 不同版本的jar包,此时就会导致某些情况下报加载不到类的错误。

  还有如果多个应用使用同一jar包文件,当放置了多份,就可能导致 多个应用间 出现类加载不到的错误。

猜你喜欢

转载自blog.csdn.net/liyingying111111/article/details/82623041