Tomcat类加载器
java本身的类加载器是双亲委派机制,而tomcat的应用场景是需要web应用类库隔离的,为了避免应用包之间相互影响,所以java原生的双亲委派是不可以在tomcat中使用了

可以看到tomcat实现了自己的类加载器模型,在catalina.properties中进行配置
1 | "${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar" = |
- Common 以System为父类加载器,位于tomcat应用服务器顶层的公用类加载器,使用common.loader进行配置。可以负责加载Tomcat应用服务器内部和Web应用均可见的类,如Servlet规范相关包以及一些通用的工具包
- Catalina 以common为父加载器,用于加载tomcat应用服务器的类加载器,使用server.loader进行配置,默认为空,即使用common类加载器加载应用服务器。可以负责加载只有Tomcat应用服务器内部可见的类,这些类对Web应用不可见
- Shared 以common为类加载器,是所有web应用的父加载器,使用shared.loader进行配置,默认为空,即使用common类加载器作为web应用的父加载器。可以负责加载web应用共享的类
- Web应用 以Shared为父加载器,加载/WEB-INF/classes目录下的未压缩的class和资源文件以及/WEB-INF/lib下的jar包,只对当前web应用可见
加载过程
当进行类加载时,除JVM基础类库外,会首先尝试通过当前类加载器加载,然后才会进行委派。Servlet规范相关的API禁止通过Web应用类加载器加载。因此,不要在web应用中包含这些包。如servlet-api.jar
Web应用类加载器默认加载顺序为
- 先从缓存中加载
- 如果没有,则从JVM的Bootstrap类加载器中加载
- 如果没有,则从当前类加载器加载(按照WEB-INF/classes、WEB-INF/lib的顺序)
- 如果没有,则从父类加载器加载,父类加载器采用默认的委派方式,加载顺序为System->Common->Shared
当然了,如果就想使用java原生的委派机制怎么办呢
可以看之前文章 tomcat之server配置文件的Loader节点
将delegate改为true即为使用java原生的委派机制,此时的加载顺序为
- 先从缓存中加载
- 如果没有,则从JVM的Bootstrap类加载器中加载
- 如果没有,则从父类加载器加载,父类加载器采用默认的委派方式,加载顺序为System->Common->Shared
- 如果没有,则从当前类加载器加载(按照WEB-INF/classes、WEB-INF/lib的顺序)