Launcher和ClassLoader源码分析

1.ClassLoader 源码

1.通过 ClassLoader.getSystemClassLoader() 进入源码分析。

	   public static void main(String[] args) {

        //1.获取classloader的方法
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
    }

2.进入方法

    /**
     * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
     * when this method is first invoked then the value of that property is
     * taken to be the name of a class that will be returned as the system
     * class loader.  The class is loaded using the default system class loader
     * and must define a public constructor that takes a single parameter of
     * type <tt>ClassLoader</tt> which is used as the delegation parent.  An
     * instance is then created using this constructor with the default system
     * class loader as the parameter.  The resulting class loader is defined
     * to be the system class loader
     * 会返回一个默认的ClassLoader,默认的是SystemClassLoader,如
     * 果‘java.system.class.loader’没有指定默认的加载器外。
     */
 	public static ClassLoader getSystemClassLoader() {
        initSystemClassLoader();
        if (scl == null) {
            return null;
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkClassLoaderPermission(scl, Reflection.getCallerClass());
        }
        return scl;
    }
	
	 // The class loader for the system
    // @GuardedBy("ClassLoader.class")
    //系统类加载器
    private static ClassLoader scl;

    // Set to true once the system class loader has been set
    // @GuardedBy("ClassLoader.class")
    //如果为true,则系统加载器已经初始化了
    private static boolean sclSet;
	
	//初始化系统加载器,包括初始化父加载器
	private static synchronized void initSystemClassLoader() {
        if (!sclSet) {//boolean类型的静态变量,标记是否被初始化了,解决并发问题
            if (scl != null)
                throw new IllegalStateException("recursive invocation");
             //获取Launcher类实例,jvm加载器都是它的内部类,直接去2看Launcher源码
            sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
            if (l != null) {
                Throwable oops = null;
                //scl为classloader内部的缓存静态变量,存储系统类加载器
                scl = l.getClassLoader();
                try {
                	//是否用户指定了默认的加载类
                    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;
        }
    }
  
  //检测用户是否自定义设置了默认的加载类
class SystemClassLoaderAction
    implements PrivilegedExceptionAction<ClassLoader> {
    private ClassLoader parent;

    SystemClassLoaderAction(ClassLoader parent) {
        this.parent = parent;
    }

	
    public ClassLoader run() throws Exception {
    	//获取参数,如果参数不为空,则值是设置的类加载器的限定名
        String cls = System.getProperty("java.system.class.loader");
        if (cls == null) {
            return parent;
        }
		//获取自定义类加载器的构造参数,必须是含参的构造参数
        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;
    }
}

2.Launcher源码

//通过调用静态方法,获取单例实例
 public static Launcher getLauncher() {
        return launcher;
    }
    
  private static Launcher launcher = new Launcher();


	//构造方法
  public Launcher() {
        // Create the extension class loader
        //创建扩展类类加载器
        ClassLoader extcl;
        try {
        	//获取到一个ExtClassLoader加载器
            extcl = ExtClassLoader.getExtClassLoader();
        } catch (IOException e) {
            throw new InternalError(
                    "Could not create extension class loader", e);
        }

        // Now create the class loader to use to launch the application
        //创建一个SystemClassLoader加载器,将extcl作为参数
        try {
            loader = AppClassLoader.getAppClassLoader(extcl);
        } catch (IOException e) {
            throw new InternalError(
                    "Could not create application class loader", e);
        }

        // Also set the context class loader for the primordial thread.
        //设定当前线程上下文使用的系统类加载器
        Thread.currentThread().setContextClassLoader(loader);

        // Finally, install a security manager if requested
        String s = System.getProperty("java.security.manager");
        if (s != null) {
            SecurityManager sm = null;
            if ("".equals(s) || "default".equals(s)) {
                sm = new java.lang.SecurityManager();
            } else {
                try {
                    sm = (SecurityManager)loader.loadClass(s).newInstance();
                } catch (IllegalAccessException e) {
                } catch (InstantiationException e) {
                } catch (ClassNotFoundException e) {
                } catch (ClassCastException e) {
                }
            }
            if (sm != null) {
                System.setSecurityManager(sm);
            } else {
                throw new InternalError(
                        "Could not create SecurityManager: " + s);
            }
        }
    }

	static class ExtClassLoader extends URLClassLoader {

        static {
            ClassLoader.registerAsParallelCapable();
        }

        /**
         * create an ExtClassLoader. The ExtClassLoader is created
         * within a context that limits which files it can read
         */
        public static ExtClassLoader getExtClassLoader() throws IOException
        {
            final File[] dirs = getExtDirs();

            try {
                // Prior implementations of this doPrivileged() block supplied
                // aa synthesized ACC via a call to the private method
                // ExtClassLoader.getContext().

                return AccessController.doPrivileged(
                        new PrivilegedExceptionAction<ExtClassLoader>() {
                            public ExtClassLoader run() throws IOException {
                                int len = dirs.length;
                                for (int i = 0; i < len; i++) {
                                    MetaIndex.registerDirectory(dirs[i]);
                                }
                                return new ExtClassLoader(dirs);
                            }
                        });
            } catch (java.security.PrivilegedActionException e) {
                throw (IOException) e.getException();
            }
        }

        void addExtURL(URL url) {
            super.addURL(url);
        }




		/****        扩展类类加载器                         ****/
       static class ExtClassLoader extends URLClassLoader { 

        /**
         * create an ExtClassLoader. The ExtClassLoader is created
         * within a context that limits which files it can read‘’
         * 创建一个扩展类类加载器,这个类加载器限制在他读的文件内
         */
        public static ExtClassLoader getExtClassLoader() throws IOException
        {
        	//获取加载的文件目录
            final File[] dirs = getExtDirs();

            try {
                // Prior implementations of this doPrivileged() block supplied
                // aa synthesized ACC via a call to the private method
                // ExtClassLoader.getContext().
				//创建并返回一个ExtClassLoader 
                return AccessController.doPrivileged(
                        new PrivilegedExceptionAction<ExtClassLoader>() {
                            public ExtClassLoader run() throws IOException {
                                int len = dirs.length;
                                for (int i = 0; i < len; i++) {
                                    MetaIndex.registerDirectory(dirs[i]);
                                }
                                return new ExtClassLoader(dirs);
                            }
                        });
            } catch (java.security.PrivilegedActionException e) {
                throw (IOException) e.getException();
            }
        }
		
		//获取ExtClassLoader加载的文件目录
       private static File[] getExtDirs() {
       		//配置参数
            String s = System.getProperty("java.ext.dirs");
            File[] dirs;
            if (s != null) {
                StringTokenizer st =
                        new StringTokenizer(s, File.pathSeparator);
                int count = st.countTokens();
                dirs = new File[count];
                for (int i = 0; i < count; i++) {
                    dirs[i] = new File(st.nextToken());
                }
            } else {
                dirs = new File[0];
            }
            return dirs;
        }     
    }


	/**
     * The class loader used for loading from java.class.path.
     * runs in a restricted security context.
     */
     //SystemClassLoader类加载器的内部类
	static class AppClassLoader extends URLClassLoader {

        public static ClassLoader getAppClassLoader(final ClassLoader extcl)
                throws IOException
        {
        	//获取加载目录
            final String s = System.getProperty("java.class.path");
            final File[] path = (s == null) ? new File[0] : getClassPath(s);

            // Note: on bugid 4256530
            // Prior implementations of this doPrivileged() block supplied
            // a rather restrictive ACC via a call to the private method
            // AppClassLoader.getContext(). This proved overly restrictive
            // when loading  classes. Specifically it prevent
            // accessClassInPackage.sun.* grants from being honored.
            //
            return AccessController.doPrivileged(
                    new PrivilegedAction<AppClassLoader>() {
                        public AppClassLoader run() {
                            URL[] urls =
                                    (s == null) ? new URL[0] : pathToURLs(path);
                            return new AppClassLoader(urls, extcl);
                        }
                    });
        }

        /*
         * Creates a new AppClassLoader
         */
        AppClassLoader(URL[] urls, ClassLoader parent) {
            super(urls, parent, factory);
        }    
    }
	/**
		可以返回查看ClassLoader源码了
	*/

项目练习地址和笔记:
github: https://github.com/mashenghao/jvn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值