1 Tomcat类加载器结构
Tomcat作为一个Web服务器,需要解决如下问题:
-
同一个Web服务器中,各个Web项目之间各自使用的Java类库要相互隔离
-
同一个Web服务器中,各个Web项目之间可以提供共享的Java类库
-
为了使服务器不受Web项目的影响,应该使服务器的类库与应用程序的类库相互独立
-
对应支持JSP的Web容器,应该支持热拔插(HotSwap)功能
为了解决如上的问题,Tomcat设计出如下的类加载器结构:
Tomcat自定义了如下几个类加载器:
-
Common ClassLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问
-
Catalina ClassLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见
-
Shared ClassLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见
-
WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见
-
JsperLoader:和WebappClassLoader一样,主要用于Jsp文件的热加载
Common,Catania,Shared ClassLoader的类路径在catalina.properties文件中配置,并且这三个类加载器的实现都是URLClassLoader
。默认情况下,只有Common ClassLoader配置了类路径,三个ClassCLoader共同使用Common ClassLoader。
2 打破双亲委派
Tomcat在初始化的时候通过Thread#setContextClassLoader
设置成了Catalina ClassLoader,使用Catalina ClassLoader来加载Tomcat使用的类,当Tomcat加载WebApp中的类时,使用WebappClassLoader
,而WebappClassLoader
重写了loadClass
方法打破了双亲委派。
Web应用默认的类加载顺序是(打破了双亲委派规则):
- 先从JVM的BootStrapClassLoader中加载。
- 加载Web应用下
/WEB-INF/classes
中的类。 - 加载Web应用下
/WEB-INF/lib/*.jap
中的jar包中的类。 - 加载上面定义的System路径下面的类。
- 加载上面定义的Common路径下面的类。
如果在配置文件中配置了<Loader delegate="true"/>
,那么就是遵循双亲委派规则,加载顺序如下:
- 先从JVM的BootStrapClassLoader中加载。
- 加载上面定义的System路径下面的类。
- 加载上面定义的Common路径下面的类。
- 加载Web应用下
/WEB-INF/classes
中的类。 - 加载Web应用下
/WEB-INF/lib/*.jap
中的jar包中的类。
网友评论