クラスローダのソースコード解析

参照
2。アーキテクチャ
III。分析ソースの
テストコード

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)プログラムが起動し
、次のようにクラスA ClassLoader.loadClass()のソースに負荷を:

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)(クラスURLClassLoader.findClassを見つける。)
この方法では、クラスのフルパス名がポイントで良いです。置き換え/リソースをロードします。この方法では、第二缶を認識しない二回?初めてで来ますリソースにロードされた。入ります

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方法ClassLoader.defineClass1()は
継続します...

公開された82元の記事 ウォンの賞賛8 ビュー70000 +

おすすめ

転載: blog.csdn.net/feivirus/article/details/104231382