系统类加载器(AppClassLoader)源码分析

可以通过ClassLoader.getSystemClassLoader()方法获取系统类加载器,下面进入到ClassLoader的该方法中查看系统类加载器如何被创建。

1、通过initSystemClassLoader()方法来初始化系统类加载器

	    public static ClassLoader getSystemClassLoader() {
        initSystemClassLoader();  //初始化系统类加载器
        if (scl == null) {   //scl是ClassLoader类的成员变量,表示系统类加载器
            return null;
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkClassLoaderPermission(scl, Reflection.getCallerClass());
        }
        return scl;
    }

2、在initSystemClassLoader()方法中, 首先会初始化Launcher类,然后调用Launcher的getClassLoader()方法获取系统类加载器。

        private static synchronized void initSystemClassLoader() {
        if (!sclSet) {  //sclSet表示一旦系统类加载器被初始化,就设置为true,
            if (scl != null)
                throw new IllegalStateException("recursive invocation");
            //获取Launcher实例,这里使用单例模式获取
            sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); 
            if (l != null) {
                Throwable oops = null;
                //通过Launcher的getClassLoader获取系统类加载器,Launcher类中维护了一个成员变量叫
                //classLoader,表示系统类加载器
                scl = l.getClassLoader();   
                try {
                    //判断是否有自定义类加载器,上面已经获取了系统类加载器,这里判断如果有
                    //自定义类加载器,就将scl赋值为自定义类加载器
                    scl = AccessController.doPrivileged(
                        new SystemClassLoaderAction(scl));
                } 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;
        }
    }

3、SystemClassLoaderAction类的实现

class SystemClassLoaderAction
    implements PrivilegedExceptionAction<ClassLoader> {
    private ClassLoader parent;    //成员变量,表示系统类加载器

    SystemClassLoaderAction(ClassLoader parent) {
        this.parent = parent;   //将传入的系统类加载器赋值给变量
    }

    public ClassLoader run() throws Exception {
        //从系统属性中获取java.system.class.loader的值,该值是一个类加载器的全限定名,代表系统类
        //加载器,默认java.system.class.loader属性为null
        String cls = System.getProperty("java.system.class.loader");
       
        //若cls为空,说明用户没有在代码中自定义累加器作为系统类加载器,则返回从
        //Launcher.getClassLoader获取的系统类加载器
        if (cls == null) {
            return parent;
        }
		//如果不为空,根据全限定类名使用Class.forName()去加载并获取到含有ClassLoader类型参数的
		//构造函数;forName的三个参数是:
		//cls:java.system.class.loader定义的类加载器的全限定名
		//true:表示初始化该类加载器,false表示不初始化该类加载器
		//parent:是系统类加载器,表示使用系统类加载器加载器cls类
        Constructor<?> ctor = Class.forName(cls, true, parent)
            .getDeclaredConstructor(new Class<?>[] { ClassLoader.class });
        //通过反射创建这个自定义类加载器的实例,并将系统类加载器(parent)传入,作为其父类
        ClassLoader sys = (ClassLoader) ctor.newInstance(
            new Object[] { parent });
        //将线程上下文类加载器设置为这个自定义类加载器
        Thread.currentThread().setContextClassLoader(sys);
        return sys;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值