zoukankan      html  css  js  c++  java
  • Tomcat架构解析(五)-----Tomcat的类加载机制

      类加载器就是根据类的全限定名(例如com.ty.xxx.xxx)来获取此类的二进制字节流的代码模块,从而程序可以自己去获取到相关的类。

      一、java中的类加载器

      1、类加载器类别

      java中的类加载器主要分为三类:

      Bootstrap ClassLoader:启动类加载器,负责加载<JAVA_HOME>lib目录中的class文件;

      Extension ClassLoader:扩展类加载器,负责加载<JAVA_HOME>libext路径下的class文件;

      Application ClassLoader:应用程序类加载器,也称为系统类加载器。负责加载用户路径上所指定的类库,开发者可以直接使用,如果开发者没有自己定义类加载器,一般就是使用此类加载器。

      类加载器的层次结构如下:

      

      

      2、双亲委派模型

      要求:除了顶层的启动类加载器之外,其他的类加载器都必须具有父类

      解释:如果一个类加载器收到了加载类的请求,首先并不会自己尝试加载这个类,而是将请求委派给父类加载器完成,父类又去委派给其父类,因此最终的请求都到了顶层,若顶层类加载器无法加载,子类再尝试自己加载。

      好处:费了这么大劲,到底有啥好处呢?

      按照双亲委派模型加载类,会让类首先有一种层次感,或者说是上下级感。最顶层的类加载器只加载<JAVA_HOME>lib下的class文件,这是jdk的核心所在,当然也是凌驾于开发者所创建的class文件。并且能够保证整个jvm中,所有的基础类,例如Object等等,

      都是同一个类。哪怕程序员自己创建了java.lang.object类,编译可以通过,但是永远不会被加载。

      3、java委派过程

    •   a、从缓存中加载;
    •   b、如果缓存中没有,则从父类尝试加载;
    •   c、如果父类加载器中没有,则从当前类加载器加载;
    •   d、如果没有,则抛出异常。

      二、Tomcat中的类加载

      Tomcat中的类加载没有遵循双亲委派模型,为啥?双亲委派说的这么吊,为什么Tomcat不使用这种方式加载类?

      Tomcat类加载器需要解决的问题:

      1、解决不同应用中使用某一第三方库的不同版本

      因为将web应用部署到Tomcat中,不同应用很有可能会使用到同一类库,例如某第三方库,并且使用了不同版本。这时如果使用jvm默认的类加载的机制,不同版本的类只会保存一种,因为他认的只有全限定名,例如com.ty.xxx.xxx.class,这样不同应用就无法

      做到隔离,显然是不行的。

      2、 部署在同一个web容器中相同的类库相同的版本可以共享

      这样做很明显是为了防止资源浪费。

      3、Tomcat作为应用服务器,也有自己所依赖的类,需要与web应用隔离

      基于安全考虑,应该让容器的类库和程序的类库隔离开来。

      4、支持jsp的热修改

      jsp的本质也是servlet,jsp在程序中使用也是编译成servlet才能发挥作用。修改jsp则是非常常见的事情,那对于类加载器来说,jsp的类名并没有更改,因此按照默认的类加载机制,会直接从方法区中去class文件。Tomcat为了解决这个问题,将每个jsp

      都对应一个类加载器,jsp发生修改后,直接销毁此类加载器,重新生成,然后加载修改后的文件。

      设计图如下:

     

      

      commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;
      catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
      sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
      WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见;

      

      Tomcat类加载器加载顺序(对于WebApp ClassLoader来说):

    •   a、从缓存中加载;
    •   b、如果没有,则从JVM的Bootstrap类加载器加载;
    •   c、如果没有,则从当前类加载器加载(按照WEB-INF/classes、WEB-INF/lib的顺序);
    •   d、如果没有,则从父类加载器加载,由于父类加载器采用默认的委派模式,因此加载顺序为Extension ClassLoader-->Application ClassLoader-->Common ClassLoader-->Shared ClassLoader
  • 相关阅读:
    python基本数据类型及其使用方法
    爬虫基础
    HTML标签marquee实现滚动效果
    Python学习之路_day_32(基于tcp协议的套接字/粘包问题)
    Python学习之路_day_31(tcp协议/socket)
    Python学习之路_day_30(单例模式,网络编程)
    Python学习之路_day_29(异常处理,元类)
    Python学习之路_day_25(面向对象之封装/多态/组合)
    Python学习之路_day_24(面向对象之继承)
    Python学习之路_day_23(面向对象)
  • 原文地址:https://www.cnblogs.com/alimayun/p/10639598.html
Copyright © 2011-2022 走看看