classloader1

http://www.blogjava.net/lhulcn618/archive/2006/05/25/48230.html
ClassLoader {
属性:classloader Parent }
public class SecureClassLoader extends ClassLoader
public class URLClassLoader extends SecureClassLoader implements Closeable
在package sun.misc下有类public class Launcher
{有内部类
	static class ExtClassLoader extends URLClassLoader
	static class AppClassLoader extends URLClassLoader
}
AppClassLoader 的Parent 为ExtClassLoader
ExtClassLoader的Parent 为null 不是 顶级的加载器(bootstrap class loader)
Bootstrap	启动Launcher 再启动AppClassLoader 和ExtClassLoader
this.getClass.getClassLoader(); // 使用当前类的ClassLoader  (当前类是由什么加载器加载的)
Thread.currentThread().getContextClassLoader(); // 使用当前线程的ClassLoader  (得到的Classloader是动态的,谁执行(某个线程),就是那个执行者的Classloader 但可以通过Thread.currentThread().setContextClassLoader(...);更改当前线程的contextClassLoader)
注意:[this.getClass.getClassLoader();  
Thread.currentThread().getContextClassLoader();  
方 法一得到的Classloader是静态的,表明类的载入者是谁;方法二得到的Classloader是动态的,谁执行(某个线程),就是那个执行者的 Classloader。对于单例模式的类,静态类等,载入一次后,这个实例会被很多程序(线程)调用,对于这些类,载入的Classloader和执行 线程的Classloader通常都不同。]
ClassLoader.getSystemClassLoader(); // 使 用系统ClassLoader,即系统的入口点所使用的ClassLoader。(注意,system ClassLoader与根 ClassLoader并不一样。JVM下system ClassLoader通常为App ClassLoader)
源码:(ClassLoader中)
    public static ClassLoader getSystemClassLoader() {
	initSystemClassLoader();
	if (scl == null) {
	    return null;
	}
	SecurityManager sm = System.getSecurityManager();
	if (sm != null) {
	    ClassLoader ccl = getCallerClassLoader();
	    if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
		sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
	    }
	}
	return scl;
    }
private static synchronized void initSystemClassLoader() {
	if (!sclSet) {
	    if (scl != null)
		throw new IllegalStateException("recursive invocation");
            sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
	    if (l != null) {
		Throwable oops = null;
		scl = l.getClassLoader();
	        try {
		    PrivilegedExceptionAction a;
		    a = new SystemClassLoaderAction(scl);
                    scl = (ClassLoader) AccessController.doPrivileged(a);
	        } catch (PrivilegedActionException pae) {
		    oops = pae.getCause();
	            if (oops instanceof InvocationTargetException) {
		        oops = oops.getCause();
		    }
	        }
		if (oops != null) {
		    if (oops instanceof Error) {
			throw (Error) oops;
		    } else {
		        // wrap the exception
		        throw new Error(oops);
		    }
		}
	    }
	    sclSet = true;
	}
    }

(ClassLoader中内部类)
class SystemClassLoaderAction implements PrivilegedExceptionAction {
    private ClassLoader parent;
SystemClassLoaderAction(ClassLoader parent) {
	this.parent = parent;
    }
    public Object run() throws Exception {
	ClassLoader sys;
	Constructor ctor;
	Class c;
	Class cp[] = { ClassLoader.class };
	Object params[] = { parent };

        String cls = System.getProperty("java.system.class.loader");
	if (cls == null) {
	    return parent;
	}
	c = Class.forName(cls, true, parent);
	ctor = c.getDeclaredConstructor(cp);
	sys = (ClassLoader) ctor.newInstance(params);
	Thread.currentThread().setContextClassLoader(sys);
	return sys;
    }
}
首先获得 父类加载器(ExtClassLoader)
   sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
if (l != null) {
	scl = l.getClassLoader();//返回AppClassLoader参考sun.misc.Launcher
再试图获取[用户希望的系统加载器]System.getProperty("java.system.class.loader");//用户自定义设置的加载器
  String cls = System.getProperty("java.system.class.loader");
	if (cls == null) {
	    return parent;//如果不存在直接返回父类加载器(即:AppClassLoader)
	}
如果存在则:
	c = Class.forName(cls, true, parent);//用父类(即:AppClassLoader)加载器加载这个class
Class cp[] = { ClassLoader.class };
	Object params[] = { parent };
ctor = c.getDeclaredConstructor(cp);
	sys = (ClassLoader) ctor.newInstance(params);
再将生成的class对象传入[父类加载器AppClassLoader]作为参数生成实例对象sys
最终返回sys。
Thread.currentThread().setContextClassLoader(sys);//此时当前线程的加载器是sys

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值