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 ...
随机推荐
- 总结: MySQL(基础,字段约束,索引,外键,存储过程,事务)操作语法
1. 显示数据库列表 show databases; # 查看当前所有数据库 show databases \G #以行的方式显示 2. 在命令行中,执行sql语句 mysql -e 'show ...
- 牛客练习赛23-A/B/C/D/F
https://www.nowcoder.com/acm/contest/156#question 链接:https://www.nowcoder.com/acm/contest/156/A来源:牛客 ...
- 43. Multiply Strings 字符串表示的大数乘法
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- 二维数组malloc
//WC[K][N] double **WC = (double**)malloc(sizeof(double*)*K); ; i < K; i++) { WC[i] = (double*)ma ...
- OC 复合
在Objective-C中复合是通过包含作为实例变量的对象指针实现的 严格来说,只有对象间的组合才叫复合 --------------------Car.h---------------------- ...
- 如何解决Css属性text-overflow:ellipsis 不起作用(文本溢出显示省略号)
如何使text-overflow:elipsis起作用? 想要使用css属性text-overflow:elipsis起到作用,样式必须跟overflow:hidden; white-space:no ...
- EhLib的行Checkbox
方法1 http://www.cnblogs.com/jupt/p/4291902.html 在Indicator中添加动态Checkbox,无需绑定数据源,支持全选 - Ehlib学习(二) 先 ...
- 一道sql 关于pivot的面试题
分析:其实它是对时间月份行转列的 表结构设计: 结果: select Name,moth,ISNULL([01],0) as Value1,ISNULL([02],0) as Value2,ISNUL ...
- MySQL5.7 主从复制配置
一.主从复制原理 MySQL 主从复制是一个异步的复制过程,主库发送更新事件到从库,从库读取更新记录,并执行更新记录,使得从库的内容与主库保持一致.每一个主从复制的连接,都有三个线程.拥有多个从库的主 ...
- oracle主从表主外键对应关系
一.首先让我们来了解下什么是主外键? 1.主键:唯一标识数据表中的某一行 1) 一个表中只能有一个主键.如果在其他字段上建立主键,则原来的主键就会取消.在ACCESS中,虽然主键不是必需的,但最好为每 ...