学习tomcat类加载器,首先得先看下jvm提供了几种类加载器,毕竟tomcat类加载器是依赖于jvm类加载器的。
jvm类加载器:引导类加载器(bootstrapclassloader)、扩展类加载器(extension classloader)、系统类加载器(又称应用类加载器,system classloader)。引导类加载器是扩展类加载器的父加载器,而扩展类加载器又是系统类加载器的父加载器。
(1) bootstrap classloader 是jvm 利用jni的方式采用c语言实现的(即它并不是java.lang.classloader的子类)。负责加载%java_home%\lib下的类库或者是由-xbootclasspath选项或使用-d选项指定sun.boot.class.path系统属性指定的类。
(2) extension classloader 由sun.misc.launcher$extclassloader实现,负责加载%java_home%\jre\lib\ext中的类库或者是由系统变量java.ext.dirs指定的类库。
(3) system classloader 由sum.misc.launcher$appclassloader实现,负责加载java应用涉及到的类。加载器可以通过classloader.getsystemclassloader()来获取
tomcat启动时,会创建几种类加载器:
1 bootstrap 引导类加载器
加载jvm启动所需的类,以及标准扩展类,位于jre/lib/ext下。
2 system 系统类加载器
加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位于catalina_home/bin下。
3 common 通用类加载器
加载tomcat使用以及应用通用的一些类,位于catalina_home/lib下,比如servlet-api.jar
4 webapp 应用类加载器
每个应用在部署后,都会创建一个唯一的类加载器。该类加载器会加载位于 web-inf/lib下的jar文件中的class 和 web-inf/classes下的class文件。
当应用需要到某个类时,则会按照下面的顺序进行类加载:
1 使用bootstrap引导类加载器加载
2 使用system系统类加载器加载
3 使用应用类加载器在web-inf/classes中加载
4 使用应用类加载器在web-inf/lib中加载
5 使用common类加载器在catalina_home/lib中加载
还有一点要讲下的是java文件放在eclipse中的src文件夹下会优先jar包中的class:
这是因为eclipse中的src文件夹中的文件java以及webcontent中的jsp都会在tomcat启动时,被编译成class文件放在 web-inf/class 中。而eclipse外部引用的jar包,则相当于放在 web-inf/lib 中。因此肯定是 java文件或者jsp文件编译出的class优先加载。
另外还需注意在 catalina_home/lib 以及 web-inf/lib 中放置了不同版本的jar包,此时就会导致某些情况下报加载不到类的错误。
还有如果多个应用使用同一jar包文件,当放置了多份,就可能导致 多个应用间 出现类加载不到的错误。
以上就是tomcat中的几种类加载器介绍的详细内容。