浅析Context Class Loader
分类: Java
转载自 薛笛的专栏http://blog.csdn.net/kabini/archive/2008/09/24/2975263.aspx
浅析Context Class Loader
1 前言
对于一般的Java应用而言,类装载器是透明的,我们在做普通的Java桌面应用程序和Web程序的时候也很少会与ClassLoader打交道。但是当我们深入地研究一些WebServer(如Tomcat)的时候,发现里面用到了很复杂的自定义类装载器体系结构,想要了解其工作过程首先就要理解它是如何载如类的。此外,当我们明明在ClassPath下指定了正确的jar包,却莫名其妙地受到ClassNotFound错误,或者我们放到ClassPath下的类没有被正确载入的时候,就需要和ClassLoader打交道了。这里我不打算讨论基本的JVM的类装载器体系结构和原理,因为这些东西已经在《Java深度历险》或者《Inside Of JVM》里讲的很透彻了。本文旨在分享一下我对于各种文档上都很少提及的Context Class Loader的一些理解。虽然不是点到为止,但是肯定多有疏漏之处,希望对此有研究的朋友留言帮我补充,现行谢过。
2准备
通常情况下,类装载器共有4种,即启动类装载器、EXT类装载器、App类装载器和自定义类装载器。他们之间的阶层情况如下图左面所示,他们都有着不同的载入规则,并且通过向上代理的方式来进行。而本文所提到的Context Class Loader并不是一种新的装载器类型,而是一种抽象的说法,它的具体表现形式为:调用Thread.getCurrentThread().getContextClassLoader()所返回的那个ClassLoader。它和JVM缺省的类装载器以及自定义类装载之间是什么关系呢?下面通过一个实验来看一下。
3 实战演练
(1)步骤一
上图进行了这样一个实验:首先一个名为Class(1)的类中启动MainThread(其实就是这个类里面有main函数的意思啦),注意这个类的名字后面标出了其所在的路径(即ClassPath),然后在里面进行测试,发现目前它的装载器和当前线程(MainThread)的ContextClassLoader都是AppClassLoader。然后Class(1)启动了一个新线程Class(2)。这里的Class(2)是一个Thread的子类,执行Class(2)代码的线程我称之为Thread-0。
(2)步骤二
上图可以看到Class(2)的装载器和ContextClassLoader同样都是AppClassLoader。随后我在Class(2)中创建了一个新的URLCLassLoader,并用这个ClassLoader来载入另一个和Class(1)不在同一个ClassPath下的类Class(3)。此时我们就可以看到变化:即载入Class(3)的装载器是URLClassLoader,而ContextClassLoader还仍然是AppClassLoader。
(2)步骤三
最后我们在Class(3)中启动了一个线程类Class(4),发现Class(4)也是由URLClassLoader载入的,而此时ContextClassLoader仍然是AppClassLoader。
在整个过程中,装载类的ClassLoader发生了变化,由于线程类Class(4)是由Class(3)启动的,所以装载它的类装载器就变成了URLClassLoader。与此同时,所有线程的ContextClassLoader都继承了生成该线程的ContextClassLoader--AppClassLoader。
如果我们在第二步的结尾执行了绿色框中的代码:setContextClassLoader(),则结果就会变成下面这个样子:
我们可以清楚地看到,由于Thread-0将其ContextClassLoader设置成了URLClassLoader,而Thread-1是在Thread-0里面生成的,所以就继承了其ContextClassLoader,变成了URLClassLoader。
浅析Context Class Loader的更多相关文章
- ClassLoader,Thread.currentThread().setContextClassLoader,tomcat的ClassLoader
实际上,在Java应用中所有程序都运行在线程里,如果在程序中没有手工设置过ClassLoader,对于一般的java类如下两种方法获得的ClassLoader通常都是同一个 this.getClass ...
- Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)
Acknowledgments I would like to thank Jacob Kjome for reviewing early drafts of this document. His c ...
- 多线程爬坑之路-Thread和Runable源码解析
多线程:(百度百科借一波定义) 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提 ...
- java多线程系类:JUC线程池:03之线程池原理(二)(转)
概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...
- Spring源码分析——资源访问利器Resource之实现类分析
今天来分析Spring的资源接口Resource的各个实现类.关于它的接口和抽象类,参见上一篇博文——Spring源码分析——资源访问利器Resource之接口和抽象类分析 一.文件系统资源 File ...
- Eclipse版本android 65535解决方案(原理等同android studio现在的分包方式)
由于工作的需要看了下Eclipse下android65535的解决方案,查了好多文档,真心的发自内心的说一句请不要再拷贝别人的博客了,害人,真害人. 接下来我说下我的实现方式,首先说下65535的最可 ...
- Java多线程系列--“JUC线程池”03之 线程池原理(二)
概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...
- java类加载器-系统类加载器
系统类加载器 系统类加载器可能都耳详能熟,但是为了完整点,还是先简单的说说系统的类加载器吧. public class Test { public static void main(String[] ...
- jdk 1.8 Executors
Class Executors java.lang.Object java.util.concurrent.Executors public class Executors extends Objec ...
随机推荐
- BZOJ 1537 cdq分治
思路: 我只是想写一下cdq-- 二维偏序 一维排序 一维cdq分治 (我忘了归并排序怎么写了,,,) 写了个sort- 复杂度是O(nlog^2n) //By SiriusRen #include ...
- B - Beautiful Year
Problem description It seems like the year of 2013 came only yesterday. Do you know a curious fact? ...
- MySql数据库中乱码问题解决方案
show variables like 'character%'; //查看当前各系统位置的字符编码格式 问题一: Incorrect string value: '\xB4\xF3\xB4\x ...
- Hadoop MapReduce编程 API入门系列之wordcount版本1(五)
这个很简单哈,编程的版本很多种. 代码版本1 package zhouls.bigdata.myMapReduce.wordcount5; import java.io.IOException; im ...
- shopping car 1.0
#!/usr/bin/env python# -*- coding: utf-8 -*-# @File : 20180510001.py# @Author: Anthony.waa# @Date : ...
- 文档控件NTKO OFFICE 详细使用说明之预览word编辑保存回服务器
1.在线预览Word文件 (1) 运行环境 ① 浏览器:支持IE7-IE11(平台版本还支持Chrome和Firefox) ② IE工具栏-Internet 选项:将www.ntko.com加入到浏览 ...
- NYOJ心急的C小加——贪心
这个题会联想到拦截导弹的题目http://codevs.cn/problem/1044/ 首先用动态规划,利用Dilworth定理解题,然而超时了(╥╯^╰╥) 关于Dilworth定理,我的理解: ...
- hdu2647 Reward 拓扑排序
此题的关键在于分层次,最低一层的人的奖金是888,第二层是888+1 …… 分层可以这样实现.建立反向图.在拓扑排序的时候,第一批入度为0的点就处于第一层,第二批处于第二层 …… 由于是逐个遍历入度为 ...
- android 自定义空间 组合控件中 TextView 不支持drawableLeft属性
android 自定义空间 组合控件中 TextView 不支持drawableLeft属性.会报错Caused by: android.view.InflateException: Binary X ...
- LINUX的signal
linux的信号来源 1.由一个进程发给另一个进程(或本身) 2.内核发给进程 信号的特征 异步的,分为可靠信号和不可靠信号. 进程收到信号时怎么处理 1.执行信号处理程序 2.如果收到信号时处在一个 ...