• classLoader打破双亲委托机制


    思路:

    通过重写loadClass方法将加载类的对象改为自定义类加载器

    目标对象

    package com.dwz.classLoader.chapter4;
    
    public class SimpleObject {
    
    }

    类加载器对象

    package com.dwz.classLoader.chapter4;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    
    public class SimpleClassLoader extends ClassLoader{
        private final static String DEFAULT_DIR = "C:/Users/Administrator/Desktop/revert";
        
        private String dir = DEFAULT_DIR;
        
        private String classLoaderName;
    
        public SimpleClassLoader() {
            super();
        }
        
        public SimpleClassLoader(String classLoaderName) {
            super();
            this.classLoaderName = classLoaderName;
        }
    
        public SimpleClassLoader(String classLoaderName, ClassLoader parent) {
            //父委托
            super(parent);
            this.classLoaderName = classLoaderName;
        }
        
        @Override
        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            Class<?> clazz = null;
            
            if(name.startsWith("java.")) {
                try {
                    ClassLoader system = ClassLoader.getSystemClassLoader();
                    clazz = system.loadClass(name);
                    if(clazz != null) {
                        if(resolve) {
                            resolveClass(clazz);
                        }
                        return clazz;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            
            try {
                clazz = findClass(name);
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            if(clazz == null && getParent() != null) {
                getParent().loadClass(name);
            }
            return clazz;
        }
        
        /**
         * @param name (xxx.xxx.xxx.xxx)
         *     xxx/xxx/xxx/xxx.class
         */
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            String classPath = name.replaceAll("\.", "/");
            File classFile = new File(dir, (classPath + ".class"));
            if(!classFile.exists()) {
                throw new ClassNotFoundException("The class " + name + " not found under " + dir);
            }
            
            byte[] classBytes = loadClassBytes(classFile);
            if(null == classBytes || classBytes.length == 0) {
                throw new ClassNotFoundException("load the class " + name + " failed");
            }
            
            return this.defineClass(name, classBytes, 0, classBytes.length);
        }
        
        private byte[] loadClassBytes(File classFile) {
            try(ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    FileInputStream fis = new FileInputStream(classFile)) {
                byte[] buffer = new byte[1024];
                int len;
                while((len = fis.read(buffer)) != -1) {
                    baos.write(buffer, 0, len);
                }
                baos.flush();
                return baos.toByteArray();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        public String getDir() {
            return dir;
        }
    
        public void setDir(String dir) {
            this.dir = dir;
        }
    
        public String getClassLoaderName() {
            return classLoaderName;
        }
    }

    测试

    package com.dwz.classLoader.chapter4;
    
    public class SimpleClassLoaderTest {
        public static void main(String[] args) throws ClassNotFoundException {
            SimpleClassLoader simpleClassLoader = new SimpleClassLoader();
            Class<?> loadClass = simpleClassLoader.loadClass("com.dwz.classLoader.chapter4.SimpleObject");
            System.out.println(loadClass.getClassLoader());
        }
    }
  • 相关阅读:
    JS获取今天的日期
    领域模型vs数据模型,应该怎么用?
    如何让技术想法更容易被理解?
    如何做好技术 Team Leader
    回归分析中常见的“门槛模型”!
    有了数据湖,距离数据仓库消失还有几年?
    数据治理 VS 公司治理、IT治理、数仓治理
    Sentence-seven basic patterns 英语句子结构
    VM的Linux CentOS系统的VMTools的手动安装
    linux下IPTABLES配置详解
  • 原文地址:https://www.cnblogs.com/zheaven/p/12212938.html
Copyright © 2020-2023  润新知