tomcat源码阅读之载入器(Loader)
一、Java类的载入器:
双亲委派模型:

1、JVM提供了三种类型的类加载器:引导类载入器(bootstrap class loader)、扩展类载入器(extension class loader)、应用程序类载入器(也叫系统类载入器:system class loader);
2、引导类载入器用于引导启动java虚拟机;引导类载入器使用本地代码实现,用来载入jvm需要的类,以及所有java核心类,比如java.lang和java.io等包下的类。扩展类载入器载入标准扩展目录中的类,标准扩展目录是jdk/jre/lib/ext。系统类载入器会搜索在环境变量CLASSPATH中指明的路径和JAR文件,他作为自定义载入器的父类,子类只需要覆盖一些方法就可以实现自定义载入类;
3、当需要载入一个类时,会首先调用应用程序载入器(系统类载入器),应用程序载入器会将请求交给扩展类载入器,扩展类载入器又将请求交给引导类载入器,因此引导类载入器总是会首先执行载入类的任务,如果引导类载入器找不到需要载入的类,那么扩展类载入器尝试载入该类,如果扩展类载入器也找不到这个类,就由应用程序载入器执行载入任务,如果还是找不到这个类,则抛出java.lang.ClassNotFoundException异常;
4、双亲委派模型的作用是为了安全性,比如当用户编写了一个java.lang.object的类,他可以恶意的访问磁盘中的任意目录,但是在载入时双亲委派模型会交由引导类载入器载入,,结果是引导类载入器搜索其核心库,找到标准的java.lang.Object类并载入,自定义的java.lang.Object类并没有被载入,因此恶意代码不会被执行,安全性得到保障;
自定义类加载器:
1、继承java.lang.CLassLoader类;
2、重写父类的findClass方法;
通过ClassLoader的源码可以看到,findClass方法并未有实现代码,其是交由子类来实现自定义查找类并加载,一般不建议重写loadClass方法;
二、Tomcat载入器UML图:

1、Loader接口作为tomcat的载入器,webappLoader为其实现类;createClassLoader方法会创建一个webappClassLoader类型的载入器,webappClassLoader类继承自URLClassLoader(URLClassLoader最终继承自ClassLoader类)的自定义载入器;WebappLoader的对类的加载功能实现都是由这个自定义类载入器实现的;
2、createClassLoader默认会根据loaderClass的字符串变量生成一个webappClassLoader的自定义载入器,可以通过setLoaderClass改变loaderClass的值来指定自定义的类加载器,但是这个自定义的类加载必须从WebappClassLoader派生过来;
3、WebappLoader的run方法运行在一个线程中,每隔checkInterval秒的时间就扫描一次路径下的文件(checkInterval默认是15秒,可以改变),如果有文件发生改变了,则创建一个新的线程,在线程中调用Context.reload方法重新加载类(首先调用notifyContext生成一个WebappContextNotifier线程,然后在这个线程中调用Context.reload方法重新加载类);
4、webappClassLoader实现了reloader接口来实现类的自动重载,这个接口中最重要的方法modified,如果web应用程序中的某个servlet被修改了,modified会返回true,然后扫描线程会通知Context重新载入servlet类;
StandardContext默认是不支持自动重载servlet类的,要想开启这个功能,需要在server.xml文件中配置下面这样一行:
<Context path="/myApp" docBase="myApp" debug="0" reloadable="true"/>
5、WebappClassLoader作为一个自定义类载入器,考虑了优化和安全两方面,比如在resourceEntries中缓存以及功能载入过的类,在notFoundResources中缓存加载失败的类的名字,这样当再次加载同一个类,如果在resourceEntries中则直接返回,如果在notFoundResources中则直接抛出ClassNotFoundException异常;
缓存类资源的类是ResourceEntry,其中loadedClass存储了类的字节流,lastModified存储了最后一次修改时间;
6、基于安全性的考虑,WebappClassLoader不允许加载指定的类和包,代码如下:


7、WebappClassLoader.loadClass载入类时的流程:
a) 首先检查本地缓存,如果则直接返回;
b) 如果本地缓存没有,则检查上一层缓存,即调用java.lang.ClassLoader.findLoadedClass;
c) 若两个缓存都没有,则使用系统的类载入器加载;
d) 若启用了SecurityManager,则检查是否允许载入该类,如果是禁止的,则抛出ClassNotFoundException异常;
e) 如果标志位delefate打开,则调用父类载入器来载入,如果父类载入器为空,则使用系统类载入器载入;
f) 从当前仓库中载入相关类;
g) 如果当前仓库也没有,且delegate关闭,则使用父类载入器来载入,如果父类载入器为空,则使用系统类载入器载入;
h) 此时若仍未找到需要的类,则抛出ClassNotFoundException异常;
tomcat源码阅读之载入器(Loader)的更多相关文章
- tomcat源码阅读之部署器
我们知道web应用是用Context实例表示的,而Context是部署到Host实例中的,因此tomcat的部署器是关联的Host实例.Context实例可以用WAR文件部署,也可以把整个web应用的 ...
- SpringMVC源码阅读:拦截器
1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...
- Tomcat源码阅读(二)初始化
近来,我开始阅读tomcat的源码,感觉还挺清晰易懂:为了方便理解,我参考了网上的一些文章,把tomcat的组成归纳一下:整个tomcat的组成如下图所示: Tomcat在接收到用户请求时,将会通过以 ...
- tomcat源码阅读
1 工具准备 需要SVN.Maven.JDK.Eclipse.Eclipse M2插件 2 下载源码及发布包 源码在这里:http://svn.apache.org/repos/a ...
- tomcat源码阅读之Catalina和Bootstrap解析
一.Cataling类分析: 1.Catalina类是启动类,用于启动或者关闭Server对象,它包含一个Digester对象,用于解析tomcat配置文件:conf/server.xml;调用pro ...
- tomcat源码阅读之过滤器
一.Servlet过滤器: 1.介绍: Servlet过滤器本身并不生成请求和响应对象,它只提供过滤作用. Servlet过滤器能够在Servlet被调用之前检查Request对象,修改Request ...
- tomcat源码阅读之SingleThreadModel
一.接口简介: 实现了SingleThreadModel接口的servlet类只能保证在同一时刻,只有一个线程执行该servlet实例的service方法,在tomcat实现中会创建多个servlet ...
- tomcat源码阅读之session管理器(Manager)
一.UML图分析: (一) Session: Session保存了一个客户端访问服务器时,服务器专门为这个客户端建立一个session用来保存相关的会话信息,session有一个有效时间,这个时间默认 ...
- tomcat源码阅读之BackupManager
一. 配置: <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOpti ...
随机推荐
- poj3080kmp或者暴力
The Genographic Project is a research partnership between IBM and The National Geographic Society th ...
- 诡异的小bug 自动生成font标签包裹span标签中的文字
某天测试自己写的网站的时候突然发现页面上一些文字排版出现了一些奇怪的错乱,在控制台发现错乱的文字被font标签包裹着 ,但是代码中根本没用用到font标签 后来发现是因为自己不小心点了谷歌浏览器地址栏 ...
- TABLE中动态设置poplist的值跟着当前行的某些列动态变化
核心方法 OAAdvancedTableBean table = (OAAdvancedTableBean)webBean.findChildRecursive("TimeEntryTbl& ...
- iOS UI-三种简单的动画设置
一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView beginAnimations:nil context:nil]; //设置动画时长 ...
- PHP:第一章——PHP中的位运算
//位运算: /*$a & $b;//And(按位与).$a和$b都为1的被设为1: $a | $b;//(按位或).$a和$b任何一个为1的位被设为1 $a ^ $b;//Xor(按位异或) ...
- customization arm ubuntu rootfs
requirment: want to get arm ubuntu rootfs method: base on debootstrap tool, customization full funct ...
- ETL设计详解
ETL是BI项目最重要的一个环节,通常情况下ETL会花掉整个项目的1/3的时间,ETL设计的好坏直接关接到BI项目的成败.ETL也是一个长期的过程,只有不断的发现问题并解决问题,才能使ETL运行效率更 ...
- 用sql + Ado设置access的字段的默认值
procedure TFormLOrder.ModifyDB; var F: Integer; begin with TADOQuery.Create(nil) do try // Connectio ...
- python面试知识总结
1. 先做自我介绍 2. 做Python几年了?为什么选择Python?3. 学历?大学什么专业?4. 除了Python以外对其他语言有没有了解?5. 你对Python这门语言的看法?6. 在学习Py ...
- 《Python》 函数初识
一.函数: 1.函数初识: def 关键字 函数名 # def my_len() 函数名的命名规则跟变量一样,要具有描述性. 函数的优点: 减少代码的重复率 增强代码的阅读性 函数的主要目的:封装一个 ...