自定义ClassLoader的方式很多,简单的就是直接实现java.lang.ClassLoader类,重写findClass()及loadClass()方法。java.lang.ClassLoader是一个抽象类,
loadClass() - 其定义了双亲委派模型的模板方法loadClass(String,boolean),我们如果要打破双亲委派模型的话就可以直接重写该方法。
findClass() - 是作为loadClass(String,boolean)方法中的钩子方法,在父加载器找不到指定类时,会回调本类findClass()方法。
自定义类加载器
public class MyClassLoader extends ClassLoader {// 加载外部自定路径private String dir;public MyClassLoader(ClassLoader parent, String dir) {super(parent);this.dir = dir;}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {String path = name.replaceAll("\\.", "/") + ".class";try {path = dir + "/" + path;path = path.replaceAll("/+", "/");FileInputStream fis = new FileInputStream(path);ByteArrayOutputStream bos = new ByteArrayOutputStream();int b;while ((b = fis.read()) != -1) {bos.write(b);}byte[] bytes = bos.toByteArray();// 定义内存数据结构等,该方法是final方法return defineClass(name, bytes, 0, bytes.length);} catch (Exception e) {e.printStackTrace();throw new ClassNotFoundException(e.getMessage());}}}
demo:
public class ClassLoaderDemo {public static void main(String[] args) throws Exception {MyClassLoader classLoader = new MyClassLoader(ClassLoaderDemo.class.getClassLoader(), "d:/tmp/");Class<?> clazz = classLoader.loadClass("com.ext.Demo");clazz.newInstance();}}
在D盘的tmp目录下存放对应的类
执行时会加载到外部的Demo.class
