http://tomcat.apache.org/tomcat-4.1-doc/class-loader-howto.html
Tomcat的ClassLoader层次结构:
![]() | ![]() | ![]() |
![]() | Bootstrap | ![]() |
![]() | ![]() | ![]() |
源代码如下:
org.apache.catalina.startup.Bootstrap类(tomcat主类)
其中:
commonLoader =
ClassLoaderFactory.createClassLoader(unpacked, packed2, null);
创建common classloader,以AppClassLoader为父ClassLoader
catalinaLoader =
ClassLoaderFactory.createClassLoader(unpacked, packed,
commonLoader);
创建catalina classloader,以common classloader为父classloader
sharedLoader =
ClassLoaderFactory.createClassLoader(unpacked, packed,
commonLoader);
创建share classloader,以common classloader为父classloader
Thread.currentThread().setContextClassLoader(catalinaLoader);
设置ContextClassLoader为catalina classloader
org.apache.catalina.startup.ClassLoaderFactory类
ClassLoaderFactory创建的是StandardClassLoader(org.apache.catalina.loader包中)
由Bootstrap类调用Catalina类的process()方法,再调用execute()方法,再调用start()来启动Server实例。
当Tomcat开启每个Context时,是调用的StandardContext的start()方法,其中:
设置Loader为WebappLoader
然后调用:bindThread(),设置当前线程的ClassLoader为WebappLoader的ClassLoader,即为WebappClassLoader
WebappLoader的ClassLoader的赋值如下:
在WebappClassLoader中,其findClass的搜索顺序与一般的ClassLoader的搜索顺序不同。
一般的ClassLoader的搜索顺序为:
将其委托给父ClassLoader,如果父ClassLoader不能载入相应类,则才交给自己处理
但是WebappClassLoader中,其是先由自己来处理,如果不行再委托给父ClassLoader
相关源代码如下:
以下引自tomcat的说明文档,说明了加载类的顺序
Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:
- /WEB-INF/classes of your web application
- /WEB-INF/lib/*.jar of your web application
- Bootstrap classes of your JVM
- System class loader classses (described above)
- $CATALINA_HOME/common/classes
- $CATALINA_HOME/common/endorsed/*.jar
- $CATALINA_HOME/common/lib/*.jar
- $CATALINA_BASE/shared/classes
- $CATALINA_BASE/shared/lib/*.jar