`

基于Java 类加载原理实验类动态替换

 
阅读更多
   一个小实验,基于对Java类加载模型的理解,实现一个Java类动态替换的效果,仅供学习理解Java类加载机制。
关键:
(1)JVM通过类的加载器和类全名组合识别一个类。
(2)类加载器层次结构及委托加载模型
(3)自定义类加载器

示例:
(1)定义一个服务接口及其实现类:AService 和 SimpleA,提供简单的add服务。
AService
package org.demo;

public interface AService {

	public int add(int a, int b);
}


SimpleA
package org.demo;

public class SimpleA implements AService {

	@Override
	public int add(int a, int b) {
		int result = 0;
		result = a + b;
		return result;
	}

}


(2)自定义类加载器HotreplaceLoader,加载示例中需要动态替换的类
package org.demo;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

public class HotreplaceLoader extends ClassLoader {

	public HotreplaceLoader(){
		super(null);
	}
	
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		byte[] data = loadClassData(name);
		return this.defineClass(name, data, 0, data.length);
	}
	
	public byte[] loadClassData(String name) {
		try {
			name = name.replace(".", "//");
			FileInputStream is = new FileInputStream(new File(
					"E:\\loadclass\\src\\" + name + ".class"));
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int b = 0;
			while ((b = is.read()) != -1) {
				baos.write(b);
			}
			return baos.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
		Class cls = null;
		cls = findLoadedClass(name);
		if(!name.equals("org.demo.SimpleA") && cls == null){
			cls = getSystemClassLoader().loadClass(name);
		}else{
			try{
				cls = findClass("org.demo.SimpleA");
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		if (cls == null)
			throw new ClassNotFoundException(name);
		if (resolve)
			resolveClass(cls);
		return cls;
	}
	
}


(3)主进程Worker,无限循环加载目标类,并调用其服务,每次调用后休息
package org.demo;

import java.lang.reflect.Method;

public class Worker {

	public static void main(String[] args) throws Exception{
		for(;;){
			HotreplaceLoader loader = new HotreplaceLoader();
			Class cls = loader.loadClass("org.demo.SimpleA");
			//Object aService = cls.newInstance();
			//Method m = aService.getClass().getMethod("add", new Class[]{int.class, int.class});
			//Object count = m.invoke(aService, new Object[]{1, 1});
			AService as = (AService)cls.newInstance();
			int count = as.add(1, 1);
			System.out.println(String.valueOf(count));
			try{
				Thread.sleep(1000);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}

}


(4)验证
执行主进程,控制台不断打出“2”。
修改SimpleA 源码为:
public class SimpleA implements AService {

	@Override
	public int add(int a, int b) {
		int result = 0;
		result = (a + b)*2;
		return result;
	}

}

然后将编译好的字节码SimleA.class,拷贝到设定的加载目录E:\loadclass\src\替换原来的字节码文件。
控制台变化,不断打出“4”。


参考:
Java 类的热替换 —— 概念、设计与实现
http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/
分享到:
评论

相关推荐

    java 类加载器 class loader

    自定义类加载器是Java平台灵活性的一个体现,它可以用来实现动态加载、热部署等功能。创建自定义类加载器通常需要继承`java.lang.ClassLoader`,重写`findClass()`或`loadClass()`方法,从而控制类的查找和加载过程...

    Java爬虫Jsoup+httpclient获取动态生成的数据

    本文主要讲述如何利用Java编程语言中的Jsoup库和HttpClient工具包来获取和解析动态生成的数据,特别是那些通过JavaScript动态加载的数据。 ### Java爬虫基础 Java爬虫是指使用Java语言编写的一类程序,这些程序...

    《软件开发基础(Java)》实验报告-Java高级特性.docx

    `ClassFileLoader`是一个用于加载类的工具类,它接受一个Java源文件路径,通过替换路径字符串中的特定模式,构建出对应的类名,并使用`Class.forName()`方法加载类。这种方法在需要动态加载类或运行时生成字节码的...

    基于JAVA的文本编辑器+报告

    - **类与对象**:Java是一种面向对象的语言,文本编辑器项目会涉及到类的设计,如文本框、菜单栏、工具栏等类的定义。 - **事件处理**:Java中的事件监听机制对于文本编辑器至关重要,例如处理用户的点击、键盘...

    操作系统 linux 请求分页 模拟内存管理实验报告java(内含源码)

    实验指导中的源代码展示了如何用Java实现这个模拟系统。`Main`类是程序的入口点,它创建内存分区,进程,以及对应的页表。在循环中,用户可以交互选择不同的操作,如查看页表,模拟进程对内存的访问,从而触发内存...

    JAVA程序设计及实验教程

    此教程旨在帮助学生深入理解程序设计的基本原理,并通过实验环节加强理论知识的实践能力。以下是对各章节内容的详细解读: 1. **第3章:类和对象** 这一章介绍了面向对象编程的基础——类和对象。类是创建对象的...

    基于java编写的数字图像处理代码(二值化,灰度处理,卷积滤镜)

    在本文中,我们将深入探讨基于Java的数字图像处理技术,主要关注标题中提及的几个关键领域:二值化、灰度处理、RGB色彩通道过滤以及卷积滤镜。这些都是图像处理中的基本操作,广泛应用于图像分析、计算机视觉、机器...

    Java简单的记事本程序(完整代码含实验报告)

    Java简单的记事本程序是一个基于Java图形用户界面(GUI)技术开发的应用,旨在模拟Windows操作系统中的"记事本"功能。这个程序的核心是利用Java的Swing库来创建交互式的用户界面,同时结合文件输入输出流(File I/O ...

    JDBC与Java数据库编程

    同时,PreparedStatement可以防止SQL注入攻击,因为它使用占位符替换动态参数。 七、JDBC优化技巧 1. 使用PreparedStatement而非Statement,提高性能。 2. 使用连接池管理数据库连接,避免频繁创建和销毁连接。 3. ...

    KNN算法实现分类问题(JAVA)实现

    KNN,全称为K-最近邻(K-Nearest Neighbors),是一种基于实例的学习方法,也是监督学习中的一种基础算法,常用于分类和回归问题。在这个Java实现的KNN算法中,我们主要关注其在分类问题上的应用。下面将详细阐述KNN...

    java实验报告-总结.docx

    在实验六中,虽然没有具体代码,但文件操作是Java中常见的功能,可以读取和写入数据到文件,如保存和加载数组或矩阵数据。 六、异常处理 实验报告中的`IOException`表明了对输入输出操作可能抛出的异常进行了处理,...

    Java虚拟机_JVM_参数配置

    1. **替换或扩展核心类库**:如果你想覆盖或增强Java的内置功能,你可以指定一个包含修改后类的路径,这样JVM在启动时会优先使用这些类,而不是系统默认的。 2. **测试和调试**:在开发JDK或者对Java核心类库进行...

    操作系统内存置换java代码

    总结来说,这个Java项目是关于操作系统内存置换的模拟工具,使用了JFreechart来绘制图表,有助于直观展示各种页面替换算法的工作原理和效果。通过实验和分析,开发者和学习者可以更好地掌握内存管理策略,提升系统...

    java实验记事本+计算器.doc

    这个实验报告主要关注了使用Java的`java.awt`和`javax.swing`包来创建两个基本的GUI应用:一个简单的计算器和一个类似Windows记事本的文本编辑器。这两个应用的实现涉及到Java面向对象编程原则和事件处理机制。 ...

    Java命令参数说明大全

    分别用于添加和替换引导类路径。 5. **-Xnoclassgc** 禁止类卸载,所有加载的类将一直存在于内存中。 6. **-Xincgc** 启用增量垃圾回收机制。 7. **-Xloggc:** 将垃圾回收日志记录到指定文件中。 8. **-...

    Java EE常用框架.xmind

    无论是热部署或者是热加载、都是基于Java类加载器来完成的。 SpringBoot实现热部署 1、在plugin标签中加入插件 Shiro 简介 shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户...

    java学习基础

    14. **Java虚拟机(JVM)**:理解JVM的工作原理,包括类加载机制、内存模型(堆、栈、方法区等)和垃圾回收。 15. **设计模式**:学习常见的设计模式(如单例、工厂、观察者等),这些模式是解决常见问题的最佳实践...

Global site tag (gtag.js) - Google Analytics