美文网首页
双亲委派机制

双亲委派机制

作者: 小方块886 | 来源:发表于2021-04-21 23:25 被阅读0次

    为什么设计双亲委派机制:
    1.沙箱保护机制,保护jre包下的核心类不被其他加载器创建,只能由自己的引导类加载器创建
    2.保证类只有一个,不被重复创建

    手写一个自定义加载器:需要继承ClassLoader并且重写findClass方法

    public class MyClassLoadTest{
    
        static class MyclassLoad extends ClassLoader{
            private String path;
    
            public MyclassLoad(String path){
                this.path = path;
            }
    
            private byte[] loadByte(String name) throws Exception {
                name = name.replaceAll("\\.", "/");
                FileInputStream fis = new FileInputStream(path + "/" + name + ".class");
                int len = fis.available();
                byte[] data = new byte[len];
                fis.read(data);
                fis.close();
                return data;
            }
    
            @Override
            protected Class<?> findClass(String name) throws ClassNotFoundException {
                try {
                    byte[] data = loadByte(name);
                    return defineClass(name, data, 0, data.length);
                }catch (Exception e){
                    e.printStackTrace();
                    throw new ClassNotFoundException();
                }
            }
    
        }
    
    
        public static void main(String[] args) throws ClassNotFoundException {
            MyclassLoad myclassLoad = new MyclassLoad("D:/test");
            Class<?> loadClass = myclassLoad.loadClass("com.example.demotrading.bean.CancelOrderTask");
            String name = loadClass.getClassLoader().getClass().getName();
            System.out.println(name);
        }
    
    }
    

    如果需要打破双亲委派机制,需要重写loadClass方法,需要注意的是我们自定义的加载器的父加载器是应用类程序加载器,那么我们只需要在loadClass方法中,不使用parent.loadClass(name, false) 这个方法,就可以理解为打破双亲委派机制

    类加载器核心方法

    protected Class<?> loadClass(String name, boolean resolve)
                    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 (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();
                        }
                    }
                    if (resolve) {
                        resolveClass(c);
                    }
                    return c;
                }
            }
    

    重写loadClass方法:

            @Override
            protected Class<?> loadClass(String name, boolean resolve)
                    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();
    
                        // 重写后:自定义包下的类打破双亲委派
                        if (name.startsWith("com.example.demotrading")){
                            // 自定义搜索文件并加载
                            c = findClass(name);
                        }else {
                            // 有些核心类库的类还是必须要交给父加载器加载
                            c = this.getParent().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();
                        }
                    }
                    if (resolve) {
                        resolveClass(c);
                    }
                    return c;
                }
            }
    

    相关文章

      网友评论

          本文标题:双亲委派机制

          本文链接:https://www.haomeiwen.com/subject/hjftrltx.html