Tomcat类加载器

Tomcat类加载机制

类加载器功能及作用

类加载器 作用
引导类加载器BootstrapClassLoader c++编写,加载java核心库 java.*,比如rt.jar中的类,构造ExtClassLoader和AppClassLoader
扩展类加载器ExtClassLoader java编写,加载扩展库 JAVA_HOME/lib/ext目录下的jar 中的类,如classpath中的jre ,javax.*或者java.ext.dir 指定位置中的类
系统类加载器SystemClassLoader/AppClassLoader 默认的类加载器,搜索环境变量 classpath 中指明的路径
  • 引导类加载器 和 扩展类加载器 的作用不变
  • 系统类加载器正常情况下加载的是 CLASSPATH 下的类,但是 Tomcat 的启动脚本并未使用该变 量,而是加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。 位于CATALINA_HOME/bin下
  • CommonClassLoader、CatalinaClassLoader、SharedClassLoader和WebappClassLoader是Tomcat自己定义的类加载器,它们分别加载/common/、/server/、/shared/*(在tomcat 6之后已经合并到根目录下的lib目录下)和/WebApp/WEB-INF/*中的Java类库。其中WebApp类加载器和Jsp类加载器通常会存在多个实例,每一个Web应用程序对应一个WebApp类加载器,每一个JSP文件对应一个Jsp类加载器。
  1. commonLoader:Tomcat最基本的类加载器,加载Tomcat使用以及应用通用的一些类,位于CATALINA_HOME/lib下, 比如servlet-api.jar,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;
  2. catalinaLoader:Tomcat容器私有的类加载器,用于加载服务器内部可⻅类,这些类应用程序不能访问,加载路径中的class对于Webapp不可见;
  3. sharedLoader:各个Webapp共享的类加载器,用于加载应用程序共享类,这些类服务器不会依赖,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
  4. WebappClassLoader:各个Webapp私有的类加载器,每个应用程序都会有一个独一无二的Webapp ClassLoader,他用来加载 本应用程序 /WEB-INF/classes 和 /WEB-INF/lib 下的类。加载路径中的class只对当前Webapp可见;
  • 从上图的委派关系可以看出

CommonClassLoader能加载的类都可以被Catalina ClassLoader和SharedClassLoader使用,从而实现了公有类库的共用,而CatalinaClassLoader和Shared ClassLoader自己能加载的类则与对方相互隔离。
WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。
而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。

  • tomcat 8.5 默认改变了严格的双亲委派机制,当应用需要到某个类时,则会按照下面的顺序进行类加载:
  1. 使用bootstrap引导类加载器加载
  2. 如果未加载到,使用system系统类加载器加载,主要是为了防止一些基础类会被web中的类覆盖,如果加载到即返回。
  3. 如果未加载到,使用应用类加载器在WEB-INF/classes中加载
  4. 如果未加载到,使用应用类加载器在WEB-INF/lib中加载
  5. 最后还是加载不到的话,则委托父类加载器(Common ClassLoader)去加载。(在这最后一步,遵从双亲委派 机制)
  • tomcat中类的加载如下图:

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文件。

双亲委派机制

什么是双亲委派机制

  • 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操
    作,如果上级的类加载器没有加载,自己才会去加载这个类。

双亲委派机制的作用

  • 防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
  • 保证核心.class不能被篡改。通过委托方式,不会去篡改核心.class,即使篡改也不会去加载,即使 加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个.class对象。这样 保证了class执行安全(如果子类加载器先加载,那么我们可以写一些与java.lang包中基础类同名 的类, 然后再定义一个子类加载器,这样整个应用使用的基础类就都变成我们自己定义的类了。)
  • java类加载过程如下

Tomcat类加载机制

相关文章: