vlambda博客
学习文章列表

自定义实现类加载器+打破双亲委派模型思路分析

周志明老师新书:凤凰架构

public class MyClassloaderTest {

    static class MyClassLoader extends ClassLoader {
        private String classPath;

        public MyClassLoader(String classPath) {
            this.classPath=classPath;
        }

        /**
         * 双亲委派机制实现逻辑
         * 本方法打破双亲委派机制
         */

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();
                    /**
                     * 原双亲委派模型逻辑-->交给父类
                     */

//                    try {
//                        if (parent != null) {
//                            c = parent.loadClass(name, false);
//                        } else {
//                            c = findBootstrapClassOrNull(name);
//                        }
//                    } catch (ClassNotFoundException e) {
//                        // ClassNotFoundException thrown if class not found
//                        // from the non-null parent class loader
//                    }
                    if (!name.startsWith("cn.test")){
                        //比如Object.class就要双亲委派给根类加载器去加载
                        c=super.loadClass(name);
                    }
                    if (c == null) {
                        // If still not found, then invoke findClass in order
                        // to find the class.
                        long t1 = System.nanoTime();
                        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();
                    }
                }
                return c;
            }
        }

        /**
         * 加载class文件到内存中
         */

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            byte[] bytes = loadByte(name);
            //将字节数组转换为Class对象
            return defineClass(name, bytes, 0, bytes.length);
        }
        /**
         * 解析文件,读取到byte数组中
         */

        private byte[] loadByte(String name) {

            name = name.replaceAll("\\.""/");
            name =classPath+"/src/main/java/"+name+".class";
            FileInputStream fileInputStream = null;
            try {
                fileInputStream= new FileInputStream(name);
                int len = fileInputStream.available();
                byte[] bytes=new byte[len];
                fileInputStream.read(bytes);
                return bytes;
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return new byte[0];
        }
    }

    public static void main(String[] args) throws Exception{
        MyClassLoader myClassLoader = new MyClassLoader("D:/ideaProject/untitled");
        Class<?> aClass = myClassLoader.loadClass("cn.test.classloader.LoaderModelTest");
        Object obj = aClass.newInstance();
        Method method = aClass.getDeclaredMethod("sout"null);
        method.setAccessible(true);
        method.invoke(obj, null);
        System.out.println(aClass.getClassLoader().getClass().getName());
        System.out.println(aClass.getClassLoader().getParent().getClass().getName());
    }
}
在这里插入图片描述
自定义实现类加载器+打破双亲委派模型思路分析
在这里插入图片描述

不打破双亲委派模型(不重写loadClass)运行结果:
在这里插入图片描述

打破双亲委派模型(重写loadClass)运行结果:
在这里插入图片描述