zoukankan      html  css  js  c++  java
  • Java自定义类加载和ClassPath类加载器

    1 自定义类加载器:

    实现规则: 自定义类加载器,需要重写findClass,然后通过调用loadClass进行类加载(loadClass通过递归实现类的双亲委派加载)

    package com.daxin;
    
    import java.io.*;
    
    /**
     * 自定义类加载器,需要重写findClass,然后通过调用loadClass进行类加载(loadClass通过递归实现类的双亲委派加载)
     */
    public class MyClassLoader extends ClassLoader {
    
        /**
         * 设置类的路径
         */
        private String root;
    
    
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            byte[] classData = loadClassData(name);
            if (classData == null) {
                throw new ClassNotFoundException();
            } else {
                return defineClass(name, classData, 0, classData.length);
            }
        }
    
        private byte[] loadClassData(String className) {
            String fileName = root + File.separatorChar
                    + className.replace('.', File.separatorChar) + ".class";
            InputStream ins = null;
            try {
                ins = new FileInputStream(fileName);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int bufferSize = 1024;
                byte[] buffer = new byte[bufferSize];
                int length = 0;
                while ((length = ins.read(buffer)) != -1) {
                    baos.write(buffer, 0, length);
                }
                return baos.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    ins.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return null;
        }
    
    
        public void setRoot(String root) {
            this.root = root;
        }
    
        public static void main(String[] args) {
    
            MyClassLoader classLoader = new MyClassLoader();
            classLoader.setRoot("C:\temp");
    
            Class<?> testClass = null;
            try {
                testClass = classLoader.loadClass("com.daxin.classloader.StaticClassDemo");
                Object object = testClass.newInstance();
                System.out.println(object.getClass().getClassLoader());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    2 自定义ClassPath类加载器:

    类加载器的继承关系图:

    ClassPath类加载器实现源码:

    package org.apache.loadjar;
    
    import java.io.BufferedReader;
    /** 
     * 
     * 
     */
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.lang.reflect.Method;
    import java.net.URL;
    import java.net.URLClassLoader;
    import java.util.ArrayList;
    import java.util.List;
    
    public final class ExtClassPathLoader {
    
        private static Method addURL = initAddMethod();
    
        public static URLClassLoader classloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    
        /**
         * 初始化addUrl 方法.
         * 
         * @return 可访问addUrl方法的Method对象
         */
        private static Method initAddMethod() {
            try {
                // 反射获取addURL方法
                Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
                // 设置访问权限
                add.setAccessible(true);
                return add;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 加载jar classpath。
         */
        public static void loadClasspath() {
            List<String> files = getJarFiles();
            if (files == null)
                return;
            for (String f : files) {
                loadClasspath(f);
            }
    
            List<String> resFiles = getResFiles();
            if (resFiles == null)
                return;
            for (String r : resFiles) {
                loadResourceDir(r);
            }
        }
    
        private static void loadClasspath(String filepath) {
            File file = new File(filepath);
            loopFiles(file);
        }
    
        private static void loadResourceDir(String filepath) {
            File file = new File(filepath);
            loopDirs(file);
        }
    
        /** */
        /**
         * 循环遍历目录,找出所有的资源路径。
         * 
         * @param file
         *            当前遍历文件
         */
        private static void loopDirs(File file) {
            // 资源文件只加载路径
            if (file.isDirectory()) {
                addURL(file);
                File[] tmps = file.listFiles();
                for (File tmp : tmps) {
                    loopDirs(tmp);
                }
            }
        }
    
        /**
         * 循环遍历目录,找出所有的jar包。
         * 
         * @param file
         *            当前遍历文件
         */
        private static void loopFiles(File file) {
            if (file.isDirectory()) {
                File[] tmps = file.listFiles();
                for (File tmp : tmps) {
                    loopFiles(tmp);
                }
            } else {
                if (file.getAbsolutePath().endsWith(".jar") || file.getAbsolutePath().endsWith(".zip")) {
    
                    addURL(file);
                }
            }
        }
    
        /**
         * 通过filepath加载文件到classpath。
         * 
         * @param filePath
         *            文件路径
         * @return URL
         * @throws Exception
         *             异常
         */
        private static void addURL(File file) {
            try {
                addURL.invoke(classloader, new Object[] { file.toURI().toURL() });
            } catch (Exception e) {
            }
        }
    
        /**
         * 
         * 将当前classpath下jar.txt的清单jar明见加载到classpath中
         * 
         * @return
         * @throws Exception
         */
        private static List<String> getJarFiles() {
            // TODO 从properties文件中读取配置信息 如果不想配置 可以自己new 一个List<String> 然后把 jar的路径加进去
            // 然后返回
            InputStream in = ClassLoader.getSystemResourceAsStream("jar.txt");
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String line = null;
            List<String> list = new ArrayList<String>();
            try {
                line = br.readLine();
                while (line != null) {
                    list.add(line);
                    line = br.readLine();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (br != null)
                        br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return list;
        }
    
        /**
         * 从配置文件中得到配置的需要加载classpath里的资源路径集合
         * 
         * @return
         */
        private static List<String> getResFiles() {
            // TODO 从properties文件中读取配置信息略 如果不想配置 可以自己new 一个List<String> 然后把
            // jar的路径加进去 然后返回 额 如果没有资源路径为空就可以了
            return null;
        }
    
    
    }

    使用示例:

    package org.apache.action;
    
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.URLClassLoader;
    
    import org.apache.loadjar.ExtClassPathLoader;
    
    
    
    /**
     * 
     * 
     * @date 2017年8月14日 下午9:13:40
     * 
     */
    public class MainClassLoaderTest {
        public static void main(String[] args)
                throws InstantiationException, IllegalAccessException, ClassNotFoundException, Exception {
    
    
            
            ExtClassPathLoader.loadClasspath();
            
            System.out.println((URLClassLoader)ExtClassPathLoader.classloader);
            
    //        StringUtils su =new StringUtils();
    //        su.sayHello();
    ////         
    //        System.out.println(su.getClass().getClassLoader());
             
            
            
        }
    
    }
    
    // ExtClasspathLoader.loadClasspath();
    //
    //ExtClasspathLoader.loadClasspath("C:\Users\Daxin\Desktop\myjar.jar");
    //
    //StringUtils su = new StringUtils();
    //
    //su.sayHello();
    //
    //su.saySomeThing("I am daxin!");
    
    
    
    //只会读取第一行
    //ClassLoader.getSystemResource("jar.txt");
    //InputStream in = ClassLoader.getSystemResourceAsStream("jar.txt");
    //BufferedReader br =new BufferedReader(new InputStreamReader(in));
    //System.out.println(br.readLine());
  • 相关阅读:
    HDOJ 1846 Brave Game
    并查集模板
    HDU 2102 A计划
    POJ 1426 Find The Multiple
    POJ 3278 Catch That Cow
    POJ 1321 棋盘问题
    CF 999 C.Alphabetic Removals
    CF 999 B. Reversing Encryption
    string的基础用法
    51nod 1267 4个数和为0
  • 原文地址:https://www.cnblogs.com/leodaxin/p/7707766.html
Copyright © 2011-2022 走看看