Tomcat ClassLoader工作原理
ContextClassLoader工作原理
每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类
系统默认的contextClassLoader是systemClassLoader,所以一般而言java程序在执行时可以使用JVM自带的类、$JAVA_HOME/jre/lib/ext/中的类和$CLASSPATH/中的类
可以使用Thread.currentThread().setContextClassLoader(...);更改当前线程的contextClassLoader,来改变其载入类的行为
ClassLoader被组织成树形,一般的工作原理是:
1) 线程需要用到某个类,于是contextClassLoader被请求来载入该类
2) contextClassLoader请求它的父ClassLoader来完成该载入请求
3) 如果父ClassLoader无法载入类,则contextClassLoader试图自己来载入
注意:WebAppClassLoader的工作原理和上述有少许不同,它先试图自己载入类(在ContextBase/WEB-INF/...中载入类),如果无法载入,再请求父ClassLoader完成
由此可得:
- 对于WebApp线程,它的contextClassLoader是WebAppClassLoader
- 对于Tomcat Server线程,它的contextClassLoader是CatalinaClassLoader
在Java语言中,ClassLoader是以父子关系存在的,Java本身也有一定的类加载规范。在Tomcat中基本的ClassLoader层级关系如下图所示:
在Tomcat启动的时候,会初始化图示所示的类加载器。而上面的三个类加载器:CommonClassLoader、CatalinaClassLoader和SharedClassLoader是与具体部署的Web应用无关的,而WebappClassLoader则对应Web应用,每个Web应用都会有独立的类加载器,从而实现类的隔离。