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
- java类加载扩展
- 扩展类加载器-------改变JAVA的父优先类加载顺序
- 扩展类加载器-------改变JAVA的父优先类加载顺序
- 扩展类加载器的加载问题
- 使用Java扩展机制加载所有JAR包
- 使用Java扩展机制加载所有JAR包
- 使用Java扩展机制加载所有JAR包
- java三种类加载器--jre/lib/ext扩展jar加载过程
- 小扩展,动态加载
- php加载mssql扩展
- PHP扩展加载错误
- Java File类功能扩展
- Java类加载器
- Java类加载原理
- java类加载内幕
- Java类加载内幕
- Java类加载机制
- Java类加载内幕
- Ext.grid.CheckboxSelectionModel去除全选框
- 欢迎使用CSDN-markdown编辑器
- hibernate
- 如何解决ajax跨域问题
- 使用Genymotion时出现INSTALL_FAILED_CPU_ABI_INCOMPATIBLE错误
- java类加载扩展
- static_assert
- 教你如何将pdf转换成excel表格格式
- 桌面无法SVN checkout选项消失
- linux本地yum源配置
- android_design support library_TabLayout
- spring+spring mvc +mybatis+druid 实现数据库主从分离
- lightoj 1004 - Monkey Banana Problem 【dp】
- eclipse的debug模式