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
classloader1
最新推荐文章于 2025-05-27 22:29:28 发布