Tomcat:正统的类加载器架构

代码编译的结果从本地机器码转变为字节码,什么是机器码:机器码(machinecode),学名机器语言指令,有时也被称为原生码(NativeCode),是电脑的CPU可直接解读的数据。通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快的代码。什么是字节码:字节码(Bytecode)是一种包含执行程序、由一序列op代码/数据对组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需...

Tomcat:正统的类加载器架构

代码编译的结果从本地机器码转变为字节码,

什么是机器码:机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快的代码。

什么是字节码:字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。

通常情况下它是已经经过编译,但与特定机器码无关。字节码通常不像源码一样可以让人阅读,而是编码后的数值常量、引用、指令等构成的序列。

字节码主要为了实现特定软件运行和软件环境、与硬件环境无关。字节码的实现方式是通过编译器和虚拟机器。编译器将源码编译成字节码,特定平台上的虚拟机器将字节码转译为可以直接执行的指令。字节码的典型应用为Java bytecode。

开发工具将源码编译成字节码,字节码在运行时通过JVM(JAVA虚拟机)做一次转换生成机器指令,因此能够更好的跨平台运行。

Tomcat是一个类加载器,读取war包里面的字节码,然后通过JVM生成机器指令,来运行业务逻辑。通常来说,一个web服务器要解决如下几个问题:

  • 部署在同一个服务器上的两个web应用程序所使用的java类库可以实现相互隔离。这是最基本的要求,因为两个不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求一个类库在一个服务器中只有一份,服务器应当保证两个应用程序的类库可以互相独立使用。
  • 部署在同一个服务器上的两个web应用所使用的java类库可以共享。例如有10个使用spring组织的应用部署在同一个服务器上,如果把10份spring隔离存放,那么类库加载时占用的内存就很大,虚拟机有过度膨胀的风险。
  • 服务器需要尽可能保证自身的安全不受部署的应用程序影响。
  • 支持JSP应用的web服务器,大多数都需要支持HotSwap功能。

由于以上问题,在部署web应用时,单独的一个classpath就无法满足需求了。在tomcat结构中有三组目录(/common/,/server/,/shared/)可以存放java类库,另外还可以加上web应用程序自身的目录/WEB-INF/,一共四组,把java类库放置在这些目录中的含义分别如下:

  • common:类库可以被tomcat和所有的web应用程序共同使用;
  • server:类库可以被tomcat使用,对所有web应用程序都不可见
  • shared:类库可以被所有web程序共同使用,但对tomcat自己不可见
  • WEB-INF:仅被此web应用程序使用,对tomcat和其他web 应用不可见

为了支持这套目录结构,并对目录里面的类库进行加载和隔离。tomcat自定义了多个类加载器,这些类加载器按照经典的双亲委派模型来实现。
Tomcat服务器的类加载架构
深色背景的三个是jdk默认提供的。其他的是tomcat自定义的。CommonClassLoader,CatalinaClassLoader,SharedClassLoader和WebappClassLoader分别加载common,server,shared,和WEB-INF中的java类库。其中webapp类加载器和jsp类加载器通常会存在多个实例,每一个web应用程序对应一个webapp类加载器,每一个jsp文件对应一个jsp类加载器。
Tomcat 6.x将common,server,shared三个目录默认合并到lib目录下,这个目录里面的类库相当于以前的common目录中类库的作用。

源文地址:https://www.guoxiongfei.cn/csdn/5102.html
0