`

使用自定义类加载器加载class

 
阅读更多

 

 

 

操作流程都在代码注释中:

 

 

/**
 * 自定义文件系统类加载器 ---->使用自定义类加载器加载 某一目录下的字节码 
 * @author 
 * 将d:/myjava/com/zm/HelloWorld.class 通过自定义类加载器加载
 * 
 * 1 extends ClassLoader 重写findClass(String name)
 * 2 findClass(String name)内先去findLoadedClass(name)中找 没找到在去parent.loadClass(name)找,在没找到则用自己的代码
 *   写流获取目标文件的byte[]
 * 3 根据  c = defineClass(name, classData, 0,classData.length);得到Class对象并返回即可
 *
 */
public class FileSystemClassLoader extends ClassLoader {
	
	// d:/myjava/      
	private String rootDir;
	
	public FileSystemClassLoader(String rootDir){
		this.rootDir = rootDir;
	}
	
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		// 先去加载器里面看看已经加载到的类中是否有这个类
		Class<?> c = findLoadedClass(name); // loader.loadClass("com.zm.HelloWorld");
		
		//应该要先查询有没有加载过这个类。如果已经加载,则直接返回加载好的类。如果没有,则加载新的类。
		if(c!=null){
			return c;
		}else{
			ClassLoader parent = this.getParent();
			try {
				c = parent.loadClass(name);	   //委派给父类加载  调用JVM委托机制来加载,如果一层层上抛都没有加载到com.zm.HelloWorld的话 则走到46行 调用自己的类加载
			} catch (Exception e) {
//				e.printStackTrace();
			}
			
			if(c!=null){
				return c;
			}else{// 
				byte[] classData = getClassData(name);
				if(classData==null){
					throw new ClassNotFoundException();
				}else{
					// 将字节码处理成 Class实例返回
					c = defineClass(name, classData, 0,classData.length);
				}
			}
			
		}
		
		return c;
		
	}
	
	// 读取流 将读到的流处理成字节码数组返回
	private byte[] getClassData(String classname){   //com.zm.HelloWorld   d:/myjava/  com/zm/HelloWorld.class
		String path = rootDir +"/"+ classname.replace('.', '/')+".class";
		
//		IOUtils,可以使用它将流中的数据转成字节数组
		InputStream is = null;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try{
			is  = new FileInputStream(path);
			
			byte[] buffer = new byte[1024];
			int temp=0;
			while((temp=is.read(buffer))!=-1){
				baos.write(buffer, 0, temp);
			}
			
			return baos.toByteArray();
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}finally{
			try {
				if(is!=null){
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(baos!=null){
					baos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	
	
	
}




2 


public class Demo03 {
	public static void main(String[] args) throws Exception{
		FileSystemClassLoader loader = new FileSystemClassLoader("d:/myjava");
		FileSystemClassLoader loader2 = new FileSystemClassLoader("d:/myjava");
		
		Class<?> c = loader.loadClass("com.zm.HelloWorld");
		Class<?> c2 = loader.loadClass("com.zm.HelloWorldd");
		Class<?> c3 = loader2.loadClass("com.zm.HelloWorld");

		Class<?> c4 = loader2.loadClass("java.lang.String");
		Class<?> c5 = loader2.loadClass("com.zm.HelloWorld");
		
		
		System.out.println(c.hashCode());
		System.out.println(c2.hashCode());
		System.out.println(c3.hashCode());	//同一个类,被不同的加载器加载,JVM认为也是不相同的类
		System.out.println(c4.hashCode());
		System.out.println(c4.getClassLoader());	//引导类加载器
		System.out.println(c3.getClassLoader());	//自定义的类加载器
		System.out.println(c5.getClassLoader());	//系统默认的类加载器
		
	}
}

 

 

分享到:
评论

相关推荐

    自定义Java类加载器demo

    自定义Java类加载器demo,自定义了一个classLoader,重写了loadClass 和findClass,注意 loadClass打破了双亲委派机制,所有的类都要在自定义的class文件中找到,而findClass遵循了双亲委派机制

    JCL:Jar Class Loader,一个可配置的动态自定义类加载器,旨在在IoC框架和Web应用程序中创建,管理和操作隔离的Java类加载器。

    JCL是可配置,动态和可扩展的自定义类加载器,可直接从Jar文件和其他来源加载Java类。 这样做的动机是创建隔离的类加载器,该类加载器可以轻松地与IoC框架(如Spring)和Web应用程序集成。 整个库,包括其代码库和...

    掌握Java类加载器

    Java允许使用不同的类加载器,甚至自定义的类加载器。类加载器从源文件(通常是.class 或 .jar文件)获得不依赖平台的字节码,然后将它们加载到JVM内存空间,所以它们能被解释和执行。默认状态下,应用程序的每个类...

    Android中动态载入自定义类

    通过DexClassLoader类加载器来解析优化前面的dex文件 通过DexClassLoader的loadClass函数来载入类 通过获得到的类的newInstance函数来生成需要的对象 开始使用获取到的动态类对象~\(≧▽≦)/~啦啦啦

    java 类加载器 双亲委派 根加载器、扩展类加载器、系统类加载器

    类加载器分为根加载器(bootstrap classloader)、扩展类加载器(ext classloader)、系统类加载器(system classloader)、自定义类加载器(通常继承java.net.URLClassLoader,重写findClass()),它们的关系通常...

    executable-war-example:示例Maven项目显示了如何使用自定义类加载器使Java WAR文件像JAR一样可执行

    它使用自定义类加载器从Web存档(WAR)中的备用路径或JAR加载类。这有什么用? 考虑一个也应该具有命令行界面的Web应用程序。 当然,您将创建三个模块,并将业务逻辑移至一个模块,并将Web应用程序和CLI移至其他...

    Java虚拟机JVM类加载初始化

    1):本地编译好的class中直接加载 2):网络加载:java.net.URLClassLoader可以加载url指定的类 3):从jar、zip等等压缩文件加载类,自动解析jar文件找到class文件...而由用户自定义的类加载器所加载的类会被卸载掉!

    DynamicNativeAgent:在没有工具或自定义类加载器的情况下重新定义Java类

    DynamicNativeAgent DynamicNativeAgent可以使用本机库重新定义Java类(无需类加载器或Instrumentation)用法AgentFactory . loadNative(); // Load the native in the JVMNativeAgent agent = AgentFactory . ...

    MD5Util.class

    class文件,用于自定义ClassLoader加载文件使用; 类加载器是负责加载类的对象。ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。一般策略是将名称转换为某个...

    case-class-generator:在运行时动态定义和加载Scala类。 有助于将JSON模式快速转换为Scala案例类

    因此,现在我正在使用和生成案例类的字节码,并使用自定义类加载器加载新创建的类。 动态生成的类可用于在运行时实例化新对象,或用作类型参数。 请参阅下面的警告。 支持生成具有以下数据类型的任意字段的类: ...

    indexed-classloader:一个自定义的 JVM 类加载器,它索引类路径元素以获得更快的类资源位置

    索引类加载器一个自定义的 JVM 类加载器,它为类路径元素编制索引,以便更快地定位类/资源。 构建: ./make-jar.sh 要使用,将indexed-classpath.jar添加到类路径并设置-Djava.system.class.loader=org.pantsbuild....

    Android 自定义ImageAdapter 图片左右滑动效果.rar

    Android 自定义ImageAdapter构造器,实现手指控制图片左右滑动效果,范例需使用比较多的class 类,请一个一个引入。  实现的原理是 添加一ImageAdapter并设置给Gallery对象,设置一个itemclickListener并Toast被...

    Java代码保护工具全套源码(jShield)

    jShield是本人基于自定义类加载器技术开发的Java代码保护工具,可以加密保护Jar包或Class文件,适合需要保护Java程序的朋友使用和研究。 jShield是一款WinForm工具,通过图形化界面导入jar包或class文件后,即可...

    vue加载自定义的js文件方法

    怎么加载自定义的js文件 vue-插件这必须要看。然后就是自己写了。 export default{ install(Vue){ var tpl; // 弹出框 Vue.prototype.showAlter = (title,msg) =&gt;{ var alterTpl = Vue.extend({ // 1、创建...

    JVM解毒——类加载子系统

    什么是类加载器,类加载器有哪些? 多线程的情况下,类的加载为什么不会出现重复加载的情况? 什么是双亲委派机制?它有啥优势?可以打破这种机制吗? 类加载子系统 类加载机制概念 Java虚拟机把描述类的数据从...

    DelegatingGroovyClassloader

    简单委托 Groovy 类加载器描述这是一个使用自定义类加载器的简单项目。 简单的想法是嵌入 GroovyClassLoader,并且所以,能够使用 Groovy 语言的所有能力,但是这还不够。 目标是能够暴露一个普通的 ClassLoader ...

    注解的使用 注释文档的生成

    默认注解:@Deprecated @Override ......CLASS 给虚拟机的类加载器看的,#源码,.class存在, RUNTIME 用于反射 #源码,.class 字节码 存在 @Documented 这个注解可以让生成的文档,有注解的注释,默认是没有注解的注释

    Tax-Meta-Class:用于创建WordPress分类法自定义字段的类

    通过将Tax Meta Class包含在插件主题文件中,并使用其方法为WordPress分类标准(类别,标签和自定义分类标准)添加元字段,可以使用Tax Meta Class。 它的意思是非常简单明了。 该类派生自My-Meta-Box( 脚本),该...

    Spring Boot自定义拦截器之后静态资源无法加载的问题(第一版)

    1.自定义拦截器  2. 静态资源被拦截 3.从过滤器中去除静态文件 4.静态文件404解决 5.补充一下 6.遗留问题现象 1.自定义拦截器  自定义XXInterceptor实现HandlerInterceptor接口,在发送请求之前拦截,所以在...

    疯狂JAVA讲义

    9.6.5 使用类文件代替资源文件 350 9.6.6 使用NumberFormat格式化数字 350 9.6.7 使用DateFormat格式化日期 352 9.7 本章小结 355 本章练习 355 第10章 异常处理 356 10.1 异常概述 357 10.2 异常处理机制 ...

Global site tag (gtag.js) - Google Analytics