使用Tomcat怎么实现类加载器

  介绍

使用Tomcat怎么实现类加载器?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

<强> 1。Java类加载机制

类加载就是把编译生成的类文件,加载到JVM内存中(永久代/元空间)。

类加载器之所以能实现类隔离,是因为两个类相等的前提是它们由同一个类加载器加载,否则必定不相等。

JVM在加载时,采用的是一种双亲委托机制,当类加载器要加载一个类时,加载顺序是:

首先将请求委托给父加载器,如果父加载器找不到要加载的类然后再查找自己的存储库尝试加载

这个机制的好处就是能够保证核心类库不被覆盖。

而按照Servlet规范的建议,Webapp加载器略有不同,它首先会在自己的资源库中搜索,而不是向上委托,打破了标准的委托机制,来看下Tomcat的设计和实现。

<强> 2。Tomcat类加载器设计

Tomcat整体类加载器结构如下:

使用Tomcat怎么实现类加载器

其JDK中内部提供的类加载器分别是:

引导——启动类加载器,属于JVM的一部分,加载& lt; JAVA_HOME>/lib/目录下特定的文件扩展——扩展类加载器,加载& lt; JAVA_HOME>/lib/ext/目录下的类库的应用程序——应用程序类加载器,也叫系统类加载器,加载类路径指定的类库

<强> Tomcat自定义实现的类加载器分别是:

常见——父加载器是AppClassLoader,默认加载${卡特琳娜。回家}/lib/目录下的类库卡特琳娜-父加载器是常见的类加载器,加载卡特琳娜。服务器属性配置文件中。装载机配置的资源,一般是Tomcat内部使用的资源共享——父加载器是常见的类加载器,加载卡特琳娜。属性配置文件中共享。装载机配置的资源,一般是所有网络应用共享的资源WebappX——父加载器是共享加载器,加载/Web - inf/类的类和/Web - inf/lib/中的jar包JasperLoader——父加载器是应用加载器,加载工作目录应用编译JSP生成的类文件

在实现时,上图不是继承关系,而是通过组合体现父子关系.Tomcat类加载器的源码类图:

使用Tomcat怎么实现类加载器

常见,卡特琳娜,共享它们都是StandardClassLoader的实例,在默认情况下,它们引用的是同一个对象。其中StandardClassLoader与URLClassLoader没有区别;WebappClassLoader则按规范实现以下顺序的查找并加载:

从JVM内部的引导仓库加载从应用程序加载器路径,即类路径下加载从Web程序内的/Web - inf/类目录从Web程序内的/Web - inf/lib中的jar文件从容器常见的加载器仓库,即所有Web程序共享的资源加载

接下来看下源码实现。

<强> 3。自定义加载器的初始化

普通类加载器是在引导的initClassLoaders初始化的,源码如下:

private  void  initClassLoaders (), {   ,try  {=,,commonLoader  createClassLoader (“common",, null);   ,如果(==,,commonLoader  null ), {//才能,no  config 文件,,default 用却;能够loader 作用;might 我方表示歉意be 拷贝a  & # 39;单# 39;env。   .getClassLoader commonLoader才能=this.getClass () ();   ,}   ,//指定仓库路径配置文件前缀和父加载器,创建,ClassLoader 实例=,,catalinaLoader  createClassLoader (“server",, commonLoader);=,,sharedLoader  createClassLoader (“shared",, commonLoader);   ,}catch  (Throwable  t), {   ,log.error (“Class  loader  creation  threw  exception",, t);   1,system . exit ();   ,}   }

可以看到分别创建了三个类加载器,createClassLoader就是根据配置获取资源仓库地址,最后返回一个StandardClassLoader实例,核心代码如下:

private  ClassLoader  createClassLoader(名称、String  ClassLoader 父母)   ,throws  Exception  {      ,String  value =, CatalinaProperties.getProperty(时间+ name “.loader");   ,if  ((value ==, null), | |, (value.equals (“;”)))   return 才能;家长;,//,如果没有配置,则返回传入的父加载器   ,ArrayList  repositoryLocations =, new  ArrayList ();   ,ArrayList  repositoryTypes =, new  ArrayList ();   ,……   ,//获取资源仓库路径   ,String [] locations =, (String []), repositoryLocations.toArray (new 字符串[0]);   ,整数[]types =,(整数[]),repositoryTypes.toArray (new 整数[0]);   ,//创建一个,StandardClassLoader 对象   ,ClassLoader  ClassLoader =ClassLoaderFactory.createClassLoader   ,,(位置,类型,父);   ,……   ,return 类加载器;   }

使用Tomcat怎么实现类加载器