常用的ClassLoader的加载范围

[b]WebAppClassLoader[/b]装载器装作文件的范围:
会加载WEB-INF/lib/*和WEB-INF/classes/*
如果加载失败会交给上级AppClassLoader进行加载。
[b]AppClassLoader[/b]装载器装作文件的范围:
加载的顺序为
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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值