ClassLoader source code analysis

A reference
two. Architecture
III. Analysis of source
test Code

public static void main(String[] args) {
    try {
        ClassLoaderTest test = new ClassLoaderTest();
        ClassLoader classLoader = test.getClass().getClassLoader();
        Class clazz = classLoader.loadClass("com.feivirus.classloader.A");

        A a = (A)clazz.newInstance();

        System.out.println(a);

    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    } catch (IllegalAccessException ex) {
        ex.printStackTrace();;
    } catch (InstantiationException ex) {
        ex.printStackTrace();
    }
}

. (A) program starts
loading into the Class A ClassLoader.loadClass () source as follows:

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
{
    synchronized (getClassLoadingLock(name)) {
        // First, check if the class has already been loaded
        //调用native方法,检查类是否已经被加载过
        Class<?> c = findLoadedClass(name);
        if (c == null) {
        	//做类加载的时间性能统计
            long t0 = System.nanoTime();
            try {
                if (parent != null) {
                	//第一次进来,递归调用父类加载器,扩展类加载器,双亲委派加载模型
                    c = parent.loadClass(name, false);
                } else {
                    //第二次进来,扩展类加载器调用父类的加载器,Bootstrap类加载器,这个里面是native方法
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
                // ClassNotFoundException thrown if class not found
                // from the non-null parent class loader
            }

            if (c == null) {
            	//在扩展类加载器的调用层级,进到这里,即Bootstrap也没有加载目标类
                // If still not found, then invoke findClass in order
                // to find the class.
                long t1 = System.nanoTime();
                //进入URLClassLoader.findClass
                c = findClass(name);

                // this is the defining class loader; record the stats
                sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }
        }
        if (resolve) {
            //调用native方法解析Class对象   
            resolveClass(c);
        }
        return c;
    }
}

(B) Find the class URLClassLoader.findClass ()
In this method the full path name of the class is good in the points. Replaced / Load Resource. This method comes in twice? First time not recognize, the second can loaded into the resource. enter

private Class<?> defineClass(String name, Resource res) throws IOException {
    long t0 = System.nanoTime();
    int i = name.lastIndexOf('.');
    //url指向class文件的路径,点号格式
    URL url = res.getCodeSourceURL();
    if (i != -1) {
        //取出包路径
        String pkgname = name.substring(0, i);
        // Check if package already loaded.
        Manifest man = res.getManifest();
        //读取manifest文件
        definePackageInternal(pkgname, man, url);
    }
    // Now read the class bytes and define the class
    java.nio.ByteBuffer bb = res.getByteBuffer();
    if (bb != null) {
        // Use (direct) ByteBuffer:
        CodeSigner[] signers = res.getCodeSigners();
        CodeSource cs = new CodeSource(url, signers);
        sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
        return defineClass(name, bb, cs);
    } else {
        //第一次进入这里,读取class文件的字节
        byte[] b = res.getBytes();
        // must read certificates AFTER reading bytes.
        CodeSigner[] signers = res.getCodeSigners();
        CodeSource cs = new CodeSource(url, signers);
        sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
        //调用native方法,把字节流转成Class对象
        return defineClass(name, b, 0, b.length, cs);
    }
}

(C) .native method ClassLoader.defineClass1 ()
Continued ...

Published 82 original articles · won praise 8 · views 70000 +

Guess you like

Origin blog.csdn.net/feivirus/article/details/104231382