java类加载扩展

来源:互联网 发布:mac下映射网络驱动器 编辑:程序博客网 时间:2024/05/02 02:00
  • URLClassLoader加载类
    该类加载器用于从指向 JAR 文件和目录的 URL 的搜索路径加载类和资源。
  • 从class文件字节流加载
    通过调用ClassLoader类的defineclass()方法加载类;
    将一个 byte 数组转换为 Class 类的实例。必须分析 Class,然后才能使用它。
  • 从jar文件字节流动态加载类
    通过JarFile 和JarEntry分析Jar文件条目,读取相应的class byte[], 调用definclass 加载;
    JarInputStream 需要先转成File 在转换成JarFile进行加载

完整代码

package com.yun.hop.commons.classloader;import com.shuyun.evtsvc.EventProcessContext;import org.apache.commons.io.FileUtils;import org.apache.commons.io.IOUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.File;import java.io.IOException;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import java.util.Enumeration;import java.util.Hashtable;import java.util.List;import java.util.jar.JarEntry;import java.util.jar.JarFile;/** * Created by hop 2016/4/7. * description: */public class ByteClassLoader extends URLClassLoader {    //缓存加载的Class类    private final Hashtable<String, Class> cache = new Hashtable();    private static Logger LOG = LoggerFactory.getLogger(ByteClassLoader.class);    public ByteClassLoader(ClassLoader parent) {        super(new URL[0], parent);    }    //从class文件的字节数组byte[]加载class    public synchronized Class loadClass(String name, byte[] clazz, boolean resolve)            throws ClassNotFoundException {        if (name.startsWith("java.")) {            return findSystemClass(name);        }        Class c = (Class) cache.get(name);        if (c == null) {            c = defineClass(name, clazz, 0, clazz.length);            cache.put(name, c);        } else {            LOG.info("loadClass: found " + name + " in cache.");        }        if (resolve) {            resolveClass(c);        }        return c;    }    //从jar文件的字节数组加载jar包中的类    public synchronized Class loadClassFromJar(String className, byte[] jarFileBytes, boolean resolve)            throws ClassNotFoundException {        File tempFile = null;        JarFile jarFile = null;        String jarEntryName = className.replaceAll("\\.", "\\/") + ".class";        try {            //通过把jar字节数组写到临时文件的方式加载            tempFile = File.createTempFile("tempJarFile", "jar");            FileUtils.writeByteArrayToFile(tempFile, jarFileBytes);            jarFile = new JarFile(tempFile);            Enumeration<JarEntry> jarEntrys = jarFile.entries();            while (jarEntrys.hasMoreElements()) {                JarEntry jarEntry = jarEntrys.nextElement();                if (jarEntry.getName().equals(jarEntryName)) {                    byte bytes[] = IOUtils.toByteArray(jarFile.getInputStream(jarEntry));                    return loadClass(className, bytes, true);                }            }        } catch (IOException e) {            LOG.error(e.getMessage(), e);        } finally {            try {                if (jarFile != null) {                    jarFile.close();                }                if (tempFile != null) {                    tempFile.delete();                }            } catch (Exception e) {                LOG.error(e.getMessage(), e);            }        }        return null;    }    public void testUrlClassloader(File file) {        try {            URL[] urls = new URL[1];            urls[0] = file.toURI().toURL();            //URLClassLoader 从本地jar文件加载相应的类            URLClassLoader urlClassLoader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());            Class.forName("com.yun.hop.apitest.Out", true, urlClassLoader);            Class classz = Class.forName("com.yun.hop.apitest.OutA", true, urlClassLoader);            Object object = classz.newInstance();            Method method = classz.getMethod("out", String.class);            method.invoke(object, "Hello test testUrlClassloader");        } catch (Exception e) {            LOG.error(e.getMessage(), e);        }    }    public void testClassLoaderFromJar() {        String filePath = "F:/class/apitest-0.0.1-SNAPSHOT.jar";        try {            Class classz1 = loadClassFromJar("com.yun.hop.apitest.Out", //                    IOUtils.toByteArray(FileUtils.openInputStream(new File(filePath))), //                    true);            Class classz = loadClassFromJar("com.yun.hop.apitest.OutA", //                    IOUtils.toByteArray(FileUtils.openInputStream(new File(filePath))), //                    true);            Object object = classz.newInstance();            Method method = classz.getMethod("out", String.class);            method.invoke(object, "Hello test testClassLoaderFromJar");        } catch (Exception e) {            LOG.error(e.getMessage(), e);        }    }    public void testClassLoader() {        try {            Class classz1 = loadClass("com.yun.hop.apitest.Out", //                    IOUtils.toByteArray(FileUtils.openInputStream(new File("F:/class/Out.class"))),//                    true//            );            Class classz = loadClass("com.yun.hop.apitest.OutA", //                    IOUtils.toByteArray(FileUtils.openInputStream(new File("F:/class/OutA.class"))),//                    true//            );            Object object = classz.newInstance();            Method method = classz.getMethod("out", String.class);            method.invoke(object, "Hello test classloader");        } catch (Exception e) {            LOG.error(e.getMessage(), e);        }    }    public static void main(String args[]) {        ByteClassLoader byteClassLoader = new ByteClassLoader(Thread.currentThread().getContextClassLoader());        byteClassLoader.testUrlClassloader(new File("F:/class/apitest-0.0.1-SNAPSHOT.jar"));        byteClassLoader.testClassLoader();        byteClassLoader.testClassLoaderFromJar();    }}
1 0
原创粉丝点击