Java虚拟机利用类加载器将类载入内存,以供使用。在此过程中类加载器要做很多的事情,例如读取字节数组、验证、解析、初始化等。而Java提供的URLClassLoader类能方便地将jar、class或网络资源加载到内存。Tomcat中则用一个工厂类ClassLoaderFactory把创建类加载器的细节进行封装,通过它可以很方便地创建自定义的类加载器。

 

如上图,利用createClassLoader方法并传入资源路径跟父类加载器即可创建一个自定义类加载器,此类加载器负责加载传入的所有资源。

ClassLoaderFactory有个内部类Repository,它就是表示资源的类,资源的类型用一个RepositoryType枚举表示,即public static enum RepositoryType {DIR,GLOB,JAR,URL}。每个类型代表的意思如下:

DIR:表示整个目录下的资源,包括所有clsss、jar包及其它类型资源。

GLOB:表示整个目录下所有jar包资源,仅仅是.jar后缀的资源。

JAR:表示单个jar包资源。

URL:表示网络上得某个jar包资源。

通过以上介绍已经对ClassLoaderFactory类有所了解,下面用一个简单的例子展示tomcat中的CommonLoader是如何利用ClassLoaderFactory工厂类来创建的,如下:

List<Repository> repositories = new ArrayList<Repository>();

Repositories.add(new Repository(“${catalina.home}/lib”,RepositoryType.DIR));

Repositories.add(new Repository(“${catalina.home}/lib”,RepositoryType.GLOB));

Repositories.add(new Repository(“${catalina.base}/lib”,RepositoryType.DIR));

Repositories.add(new Repository(“${catalina.base}/lib”,RepositoryType.GLOB));

ClassLoader parent = null;

ClassLoader commonLoader = ClassLoaderFactory.createClassLoader(repositories, parent);

OK,至此CommonLoader创建完毕。其中${catalina.home}跟${catalina.base}表示变量,它的值分别为tomcat安装目录与tomcat的工作目录,您只需要替换成实际路径即可。Parent为父类加载器,如果设置为null,ClassLoaderFactory创建时会使用默认的父类加载器,即系统类加载器systemClassLassLoader。实际上,您只需以下几步就能完成一个类加载器的创建,首先,把要加载的资源都添加到一个List中;其次,确定父类加载器,默认的话就设置为null;最后,把这些作为参数传入ClassLoaderFactory工厂类。

假如我们不确定要加载的资源是在网络上的还是本地的,那么可以用以下方式进行处理:

try {

     URL url = new URL(“路径”);

     repositories.add(new Repository(“路径”, RepositoryType.URL));

     } catch (MalformedURLException e) {

 }

这种方式处理得比较巧妙,URL在实例化时就可以检查这个路径的有效性,假如为本地资源或者网络上不存在此路径的资源,那么将抛出异常,不会把此路径添加到资源列表。

在此有必要对ClassLoaderFactory工厂类的createClassLoader进行简单说明,它是一个重载方法,参数列表不同,但是不管怎样,最终都要转成URL[]数组,因为ClassLoaderFactory生产的类加载器是继承于URLClassLoader,而URLClassLoader的构造函数只支持URL[]数组。从Repository类转成URL[]数组可分为以下情况:

① 若为RepositoryType.URL类型的资源,则直接new一个URL实例添加到URL[]数组即可。

② 若为RepositoryType.DIR类型的资源,则要把File类型转化为URL类型,由于URL类用于网络,带有明显的协议,于是把本地文件的协议定为file,即处理为new URL(“file:/D:/test/”),最后的”/”切记要加上,它表示D盘test整个目录下的所有资源,最后把这个URL实例添加到URL[]数组中。

③ 若为RepositoryType.JAR类型的资源,则跟②中类似,本地文件协议为file,处理为new URL(“file:/D:/test/test.jar”),然后把这个URL实例添加到URL[]数组中。

④ 若为RepositoryType.GLOB类型的资源,则找到某个目录下的所有文件,然后依个判断是不是以.jar后缀结尾,如果是,则跟③一样转化,再将URL实例添加到URL[]数组中。如果不是以.jar结尾,则直接忽略。

现在对类加载器工厂ClassLoaderFactory有了更深的了解,知道了怎样轻松建立一个类加载器实例,并且了解了其中的细节实现。

喜欢研究java的同学可以交个朋友,下面是本人的微信号:

Tomcat内核之类加载器工厂的更多相关文章

  1. 还是Tomcat,关于类加载器的趣味实验

    一.前言 类加载器,其实是很复杂一个东西,想等到我完全什么都弄明白了再写出来,估计不太现实...现在只能是知道多少写多少吧. 首先,我提一个问题:在我们自己的servlet中(比如ssm中,contr ...

  2. Tomcat实现自定义类加载器

    什么是类加载器? 这是官方给的定义 在 Java 虚拟机的实现中,初始类可以作为命令行参数提供. 或者,该实现可以提供一个初始类,该类设置一个类加载器,该类加载器依次加载应用程序. 初始类的其他选择也 ...

  3. Tomcat源码分析 (五)----- Tomcat 类加载器

    在研究tomcat 类加载之前,我们复习一下或者说巩固一下java 默认的类加载器.楼主以前对类加载也是懵懵懂懂,借此机会,也好好复习一下. 楼主翻开了神书<深入理解Java虚拟机>第二版 ...

  4. Tomcat源码分析(类加载与类加载器)

    Tomcat的挑战 Tomcat上可以部署多个项目 Tomcat的一般部署,可以通过多种方式启动一个Tomcat部署多个项目,那么Tomcat在设计时会遇到什么挑战呢? Tomcat运行时需要加载哪些 ...

  5. tomcat: 类加载器

    一.tomcat是个web容器,要解决以下问题 1. 一个web容器可能要部署两个或者多个应用程序,不同的应用程序,可能会依赖同一个第三方类库的不同版本,因此要保证每一个应用程序的类库都是独立.相互隔 ...

  6. Tomcat与spring的类加载器案例

    Tomcat与spring的类加载器案例接下来将介绍<深入理解java虚拟机>一书中的案例,并解答它所提出的问题.(部分类容来自于书中原文) Tomcat中的类加载器在Tomcat目录结构 ...

  7. 学习Tomcat(六)之类加载器

    通过前面的文章我们知道,Tomcat的请求最终都会交给用户配置的servlet实例来处理.Servlet类是配置在配置文件中的,这就需要类加载器对Servlet类进行加载.Tomcat容器自定义了类加 ...

  8. 4.自定义类加载器实现及在tomcat中的应用

    了解了类加载器的双亲委派机制, 也知道了双亲委派机制的原理,接下来就是检验我们学习是否扎实了,来自定义一个类加载器 一. 回顾类加载器的原理 还是这张图,类加载器的入口是c++调用java代码创建了J ...

  9. 十八、泛型 l 注解 l Servlet3.0 l 动态代理 l 类加载器基础加强

    l 泛型 l 注解 l Servlet3.0 l 动态代理 l 类加载器 泛型 1 回顾泛型类 泛型类:具有一个或多个泛型变量的类被称之为泛型类. public class A<T> { ...

随机推荐

  1. hdu5652 India and China Origins(并查集)

    India and China Origins  Accepts: 49  Submissions: 426  Time Limit: 2000/2000 MS (Java/Others)  Memo ...

  2. VB6工程在Win10系统打开提示MSCOMCTL.OCX无法加载

    解决办法: 修改.vbp文件中的 00F8754DA1}#2.1#0; MSCOMCTL.OCX 改为 00F8754DA1}#2.0#0; MSCOMCTL.OCX 中间的2.1 改为 2.0

  3. Xamarin开发缺少的android_m2repository_rxx.zip下载地址以及MD5

    android_m2repository_rxx.zip下载地址以及MD5, 注意:下载后需要改文件名,改为 MD5的值.zip  例如:android_m2repository_r29.zip 需改 ...

  4. 光电转研发:和计算机没有一点关系的专业怎么去bat类的公司

    光电 女 其实编码能力一般般,拿到百度腾讯研发offer. 一来幸运,二来真的想说行动决定了结果.研一没事就出去家教充实自己赚点钱,研二就开始找实习,去了网易,海康威视,百度实习.感觉还是吃了不少苦的 ...

  5. Architecture : Describable Command and Identifiable Data

    Architecture : Describable Command and Identifiable Data Description Terms Command A command is a fu ...

  6. vmware迁移到openstack的一些坑

    title: 安全平台迁移 tags: 新建,模板,小书匠 grammar_cjkRuby: true --- 前言 主要有三个坑: 一是如果原先虚拟机没有安装virtio驱动,要设置设备驱动为ide ...

  7. bootstrap table 和 x-editable 使用方法

    最近需要做一些数据表格,有同事推荐EasyUI,但经过比较还是选择了Bootstrap,一款极为强大的表格组件,基于Bootstrap 的 jQuery .本文还将介绍Bootstrap-editab ...

  8. 韩顺平玩转Oracle视频资料整理

    .oracle10g 11g:g(grid)表示网格技术 以baidu搜索为准,现在想使用一个软件,但是此软件在离自己非常近的地方就存在了下载地址,但是与自己非常远的地方也同样存在一个下载地址,而搜索 ...

  9. JS的replace默认只替换第一个匹配项

    1. JS的replace默认只替换第一个匹配项. 解决方法: 使用正则表达式进行匹配替换[   ①.replace(new RegExp(②,"g") ,③);   ] ①:包含 ...

  10. 微信小程序基础之开源项目库汇总

    awesome-github-wechat-weapp 是由OpenDigg整理并维护的微信小程序开源项目库集合.我们会定期同步OpenDigg上的项目到这里,也欢迎各位提交项目给我们. (链接:ht ...