- 浏览: 211528 次
- 性别:
- 来自: 北京
文章分类
WebAppClassLoader装载器装作文件的范围:
会加载WEB-INF/lib/*和WEB-INF/classes/*
如果加载失败会交给上级AppClassLoader进行加载。
AppClassLoader装载器装作文件的范围:
加载的顺序为
JRE\lib\* => JRE\lib\ext\* => JRE\classes\* => CLASSPATH\*
如果加载失败会再交给上层斤进行加载。
Tomcat负责Web应用的类加载的是org.apache.catalina.loader.WebappClassLoader,它有几个比较重要的方法:findClass(),loadClass(),findClassInternal(),findResourceInternal().
WebappClassLoader类加载器被用来加载一个类的时候,loadClass()会被调用,loadClass()则调用findClass()。后两个方法是WebappClassLoader的私有方法,findClass()调用findClassInternal()来创建class对象,而findClassInternal()则需要findResourceInternal()来查找.class文件。
通常自己实现类记载器只要实现findclass即可,这里为了实现特殊目的而override了loadClass().
即loadClass(name)(入口)->findClass(name)->findClassInternal(name)(用于创建class对象)->findResourceInternal()(寻找.class文件)
下面是自定义类加载器
引用自http://blog.sina.com.cn/s/blog_4d398d670100dmui.html
下面是精简过的代码(去除了几乎全部关于log、异常和安全控制的代码):
loadClass:
public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
Class clazz = null;
// (0) 先从自己的缓存中查找,有则返回,无则继续
clazz = findLoadedClass0(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
// (0.1) 再从parent的缓存中查找
clazz = findLoadedClass(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
// (0.2) 缓存中没有,则首先使用system类加载器来加载
clazz = system.loadClass(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
//判断是否需要先让parent代理
boolean delegateLoad = delegate || filter(name);
// (1) 先让parent加载,通常delegateLoad == false,即这一步不会执行
if (delegateLoad) {
ClassLoader loader = parent;
if (loader == null)
loader = system;
clazz = loader.loadClass(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
}
// (2) delegateLoad == false 或者 parent加载失败,调用自身的加载机制
clazz = findClass(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
// (3) 自己加载失败,则请求parent代理加载
if (!delegateLoad) {
ClassLoader loader = parent;
if (loader == null)
loader = system;
clazz = loader.loadClass(name);
if (clazz != null) {
return (clazz);
}
}
throw new ClassNotFoundException(name);
}
findClass:
public Class findClass(String name) throws ClassNotFoundException {
// 先试图自己加载类,找不到则请求parent来加载
// 注意这点和java默认的双亲委托模式不同
Class clazz = null;
clazz = findClassInternal(name);
if ((clazz == null) && hasExternalRepositories) {
synchronized (this) {
clazz = super.findClass(name);
}
}
if (clazz == null) {
throw new ClassNotFoundException(name);
}
return (clazz);
}
会加载WEB-INF/lib/*和WEB-INF/classes/*
如果加载失败会交给上级AppClassLoader进行加载。
AppClassLoader装载器装作文件的范围:
加载的顺序为
JRE\lib\* => JRE\lib\ext\* => JRE\classes\* => CLASSPATH\*
如果加载失败会再交给上层斤进行加载。
Tomcat负责Web应用的类加载的是org.apache.catalina.loader.WebappClassLoader,它有几个比较重要的方法:findClass(),loadClass(),findClassInternal(),findResourceInternal().
WebappClassLoader类加载器被用来加载一个类的时候,loadClass()会被调用,loadClass()则调用findClass()。后两个方法是WebappClassLoader的私有方法,findClass()调用findClassInternal()来创建class对象,而findClassInternal()则需要findResourceInternal()来查找.class文件。
通常自己实现类记载器只要实现findclass即可,这里为了实现特殊目的而override了loadClass().
即loadClass(name)(入口)->findClass(name)->findClassInternal(name)(用于创建class对象)->findResourceInternal()(寻找.class文件)
下面是自定义类加载器
引用自http://blog.sina.com.cn/s/blog_4d398d670100dmui.html
下面是精简过的代码(去除了几乎全部关于log、异常和安全控制的代码):
loadClass:
public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
Class clazz = null;
// (0) 先从自己的缓存中查找,有则返回,无则继续
clazz = findLoadedClass0(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
// (0.1) 再从parent的缓存中查找
clazz = findLoadedClass(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
// (0.2) 缓存中没有,则首先使用system类加载器来加载
clazz = system.loadClass(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
//判断是否需要先让parent代理
boolean delegateLoad = delegate || filter(name);
// (1) 先让parent加载,通常delegateLoad == false,即这一步不会执行
if (delegateLoad) {
ClassLoader loader = parent;
if (loader == null)
loader = system;
clazz = loader.loadClass(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
}
// (2) delegateLoad == false 或者 parent加载失败,调用自身的加载机制
clazz = findClass(name);
if (clazz != null) {
if (resolve) resolveClass(clazz);
return (clazz);
}
// (3) 自己加载失败,则请求parent代理加载
if (!delegateLoad) {
ClassLoader loader = parent;
if (loader == null)
loader = system;
clazz = loader.loadClass(name);
if (clazz != null) {
return (clazz);
}
}
throw new ClassNotFoundException(name);
}
findClass:
public Class findClass(String name) throws ClassNotFoundException {
// 先试图自己加载类,找不到则请求parent来加载
// 注意这点和java默认的双亲委托模式不同
Class clazz = null;
clazz = findClassInternal(name);
if ((clazz == null) && hasExternalRepositories) {
synchronized (this) {
clazz = super.findClass(name);
}
}
if (clazz == null) {
throw new ClassNotFoundException(name);
}
return (clazz);
}
发表评论
-
JVM启动时指定-Dfile.encoding="UTF8"的作用
2013-10-17 13:50 2280简单来说就是指定JVM默认的编码方式 java io中很多方法 ... -
java多线程 小记
2012-04-15 14:49 0thread join的方法 http://blog.csdn ... -
浅析多线程
2012-04-08 22:35 0线程组 线程是被 ... -
多线程意外中断处理
2012-04-08 20:54 0本文转自:http://peirenlei.iteye.com ... -
多线程项目学习
2012-04-08 20:35 0线程组的作用: ThreadGroup类中的某些方法,可以对线 ... -
java 静态成员变量的内存分配
2012-04-06 10:28 0静态成员变量是属于类变量,即当JVM加载class文件到虚拟机 ... -
深度克隆与浅克隆
2012-04-05 16:31 1115要想实现某个对象的克隆需要该对象实现java.lang.Clo ... -
修改图片大小并添加水印
2012-03-29 13:47 1263import java.awt.*; import java. ... -
JVM的内存分配
2012-03-16 10:06 0Java里的堆(heap)栈(stack)和方法区(metho ... -
HashMap添加数据的过程
2012-03-14 22:18 7077当添加的元素的key为null ... -
几种classloader的加载范围
2012-02-28 12:43 1310Bootstrap class loader:最顶级的clas ... -
利用正则表达式获取网页中多处重复出现的标签数据
2012-02-21 11:21 2698public static void main(String[ ... -
标准的URLConnection请求
2012-01-13 16:39 0只写了主要的代码 URL url = new URL(urlS ... -
ClassLoader.getSystemClassLoader().loadClass()和Class.forName()的区别
2012-01-13 13:08 0class A { static { System.ou ... -
httpClient超时解决办法
2012-01-12 16:47 0DefaultHttpClient: 请求超时 httpcli ... -
项目中的使用技巧小记
2012-01-10 21:11 575实现数据在多线程之间的共享: 因为线程的成员变量是各个该线程实 ... -
ThreadLocal
2012-01-10 08:55 1406ThreadLocal是实现线程范围内的数据共享,即不同线程获 ... -
线程加锁优化
2012-01-08 13:19 0实际上,在某些classes中,这种instance方法的同步 ... -
实现多线程使用继承Thread类和Runnable的原因
2012-01-03 15:09 1373我们都知道实现多线程的两种方式,一种是继承Thread类,另一 ... -
一个简单的socket编程实例
2011-12-28 10:50 1604转正于http://www.cnblogs.com/linzh ...
相关推荐
eclipse工程格式 博文链接:https://aga.iteye.com/blog/200818
具体public.xml如何编写,可参考PluginMain/res/values/public.xml 以及 PluginTest/res/values/public.xml俩个文件,它们是分别用来固定宿主程序和插件程序资源id的范围的。 4、插件apk的Context 构造一个...
1.8 Java安全性的适用范围 11 第2章 Java语言的基本安全特点 12 2.1 Java语言和平台 12 2.2 基本安全结构 13 2.3 字节代码验证和类型安全 14 2.4 签名应用小程序 15 2.5 关于安全错误及其修复的简要历史 16 第3章 ...
1.8 Java安全性的适用范围 11 第2章 Java语言的基本安全特点 12 2.1 Java语言和平台 12 2.2 基本安全结构 13 2.3 字节代码验证和类型安全 14 2.4 签名应用小程序 15 2.5 关于安全错误及其修复的简要历史 16 第3章 ...
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...
loader:可以指定一个类加载器加载字节码文件 2. 全限定类名.class 3. 对象名.getClass() Class类中方法newInstance():创建当前字节码对象(只能调用无参且是public修饰的构造...
37.classloader中,JDK的API、Classpath中的同web-inf中的class加载方式有什么区别? 38.列举三种以上垃圾回收算法,并比较其优缺点? 39.编写代码实现一个线程池 40.描述一下JVM加载class文件的原理机制? 41....
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...
4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean定义信息 4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 不同配置方式比较 4.13 小结 第5章 Spring容器高级主题 5.1 ...
4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean定义信息 4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 不同配置方式比较 4.13 小结 第5章 Spring容器高级主题 5.1 ...
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM .........................
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................