`

模拟JDK动态代理(JAVA设计模式)

 
阅读更多

JDK6提供了Javacompiler,StandardJavaFileManager,Iterable实现对.java文件编译的方法。

框架在实现代理的时候可以使用CGLIB直接生成2进制文件,不需要生成.java文件。

//接口
public interface Moveable {
	void move();
	void stop();
}

//实现Moveable接口
public class Tank implements Moveable{

	public void move() {
		System.out.println("tank move()...");
	}

	public void stop() {
		System.out.println("tank stop()...");
		
	}

}

import java.lang.reflect.Method;

//除moveable之外再创建一个接口InvocationHandler
public interface InvocationHandler {
	void invoke(Object o,Method m);
}


import java.lang.reflect.Method;

//实现InvocationHandler接口,自定义需要添加的内容,创建添加日志的Handler
public class LogHandler implements InvocationHandler{
	Object target;
	public LogHandler(Object target) {
		this.target = target;
	}
	public void invoke(Object o, Method m) {
		System.out.println("logHandler start...");
		try {
			m.invoke(target);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("logHandler end...");
	}

}

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

//模拟JDK的代理类Proxy
public class Proxy {
	//模拟JDK创建代理类的方法,JDK中还有一个ClassLoader参数,这里传入接口和需要添加的逻辑Handler,结果返回一个代理的对象。
	public static Object newProxyInstance(Class inf,InvocationHandler h) throws Exception{
		String methodStr = "";
		String rt = "\r\n";
		Method[] methods = inf.getMethods();
		for(Method m : methods){
			methodStr += "@Override" + rt + 
			 "public void " + m.getName() + "() {" + rt +
			 "    try {" + rt +
			 "    Method md = " + inf.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt +
			 "    h.invoke(this, md);" + rt +
			 "    }catch(Exception e) {e.printStackTrace();}" + rt +
			
			 "}";
		}
		
		//生成代理对象的类
		String src = 
			"package proxy;" +  rt +
			"import java.lang.reflect.Method;" + rt +
			"public class $Proxy1 implements " + inf.getName() + "{" + rt +
			"    proxy.InvocationHandler h;" + rt +
			"    public $Proxy1(InvocationHandler h) {" + rt +
			"        this.h = h;" + rt +
			"    }" + rt +
			methodStr +
			"}";
		String fileName = 
			"D:/share/test/proxy/$Proxy1.java";
		File f = new File(fileName);
		FileWriter fw = new FileWriter(f);
		fw.write(src);//生成.java文件
		fw.flush();
		fw.close();
		
		//对类进行编译
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
		Iterable units =  fileManager.getJavaFileObjects(fileName);
		compiler.getTask(null, fileManager, null, null, null, units).call();//编译,生成.class文件。
		fileManager.close();
		
		URL[] url  = new URL[]{new URL("file:/D:/share/test/")};
		URLClassLoader loader = new URLClassLoader(url);
		Constructor c = loader.loadClass("proxy.$Proxy1").getConstructor(InvocationHandler.class);//构造器有参数
		return c.newInstance(h);//加载.class文件,生成对象。
	}
}


public class Client {
	public static void main(String[] args) throws Exception {
		InvocationHandler h = new LogHandler(new Tank());//告诉代理类,我需要添加什么逻辑。
		
		Moveable m = (Moveable) Proxy.newProxyInstance(Moveable.class, h);//返回代理的对象。
		m.move();//实际这里是调用添加过逻辑的代理类的方法。
		m.stop();
	}
}

分享到:
评论

相关推荐

    静态代理动态代理测试,模拟jdk实现动态代理

    在Java编程中,代理模式是一种常用的结构型设计模式,它能提供一种在不修改原有对象的基础上,增强或扩展其功能的方式。代理模式分为静态代理和动态代理两种主要形式。 **静态代理**是程序员手动创建代理类,这个...

    《Java设计模式》课后习题参考答案-刘伟(20180723).pdf

    此外,为了确保参考资料的权威性,建议读者查阅原书《Java设计模式》以获得更加详尽的解释和说明。如果有任何意见或建议,可以通过提供的电子邮箱与作者联系。在学习设计模式的过程中,理解每一个模式的意图、结构、...

    《Java设计模式》课后习题及模拟试题答案

    《Java设计模式》是Java开发领域的一本经典教材,由刘伟编写,深入浅出地讲解了23种GOF(GoF, Gamma, Helm, Johnson, Vlissides)设计模式,旨在提升开发者在软件设计中的灵活性和可维护性。课后习题和模拟试题是...

    模拟spring aop【一】基于jdk动态代理实现的aop

    在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者定义“切面”,这些切面可以包含业务逻辑的某一部分,比如日志、事务管理或安全控制。切面可以在多个对象中统一地应用,提高了代码的复用性...

    java dtdl 动态代理

    总结,Java动态代理是Java设计模式中的一种重要工具,它为开发者提供了在运行时扩展或增强已有对象功能的能力,是实现AOP和提高代码灵活性的有效途径。理解并熟练运用动态代理,能提升软件设计的质量和可维护性。

    java中动态代理,springAop.pdf

    Java中的动态代理是一种强大的设计模式,它允许我们在运行时创建具有特定行为的代理对象,这些对象可以对原对象的方法调用进行拦截、增强或包装。Spring AOP(面向切面编程)是Spring框架的一部分,它利用了Java的...

    动态代理底层源码核心思想版

    在Java编程语言中,动态代理是一种...总结,动态代理是Java中一种强大的设计模式,通过它可以灵活地扩展对象的功能。理解其底层源码和核心思想,能够帮助开发者更有效地利用这一特性,提升代码的可维护性和可扩展性。

    学生竞赛模拟-学生竞赛模拟系统-学生竞赛模拟系统源码-学生竞赛模拟管理系统-基于Web的学生竞赛模拟系统设计与实现-java代码

    学生竞赛模拟-学生竞赛模拟系统-学生竞赛模拟系统源码-学生竞赛模拟管理系统-学生竞赛模拟管理系统java代码-学生竞赛模拟系统设计与实现-基于ssm的学生竞赛模拟系统-基于Web的学生竞赛模拟系统设计与实现-学生竞赛...

    学生竞赛模拟-学生竞赛模拟系统-学生竞赛模拟系统源码-学生竞赛模拟管理系统-基于ssm的学生竞赛模拟系统-ssm-java代码

    学生竞赛模拟-学生竞赛模拟系统-学生竞赛模拟系统源码-学生竞赛模拟管理系统-学生竞赛模拟管理系统java代码-学生竞赛模拟系统设计与实现-基于ssm的学生竞赛模拟系统-基于Web的学生竞赛模拟系统设计与实现-学生竞赛...

    监听者模式练习(包括jdk api的实现和自定义实现)

    监听者模式,也被称为观察者模式,是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在Java中,JDK提供了内置的监听器接口和类来支持...

    代理模式

    代理模式是一种设计模式,它是结构型模式的一种,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。代理模式的核心思想是提供一个代理类,这个代理类作为真实对象的代表,可以控制或扩展...

    基于java语言的浏览器设计与实现.doc

    基于 Java 语言的浏览器设计与实现 本资源摘要信息将详细介绍基于 Java 语言的浏览器设计与实现的知识点。 1. 浏览器的设计与实现 浏览器是互联网上查找信息的重要工具,给人们提供了巨大而又宝贵的信息财富。...

    动态代理

    总结来说,动态代理是Java中一种强大的设计模式,它通过在运行时创建代理对象,能够实现对现有对象行为的扩展和控制,极大地提高了代码的可维护性和灵活性。无论是标准库的`Proxy`类还是字节码库,都是实现这一功能...

    Java代码模拟公司置办货物系统

    在本项目中,我们关注的是一个名为"Java代码模拟公司置办货物系统"的应用程序。这个系统旨在模拟现实世界中的公司内部流程,特别是在购买物品时的审批和管理过程。通过这个系统,普通员工可以发起购买请求,部门经理...

    以注解方式模拟Spring IoC AOP

    - **基于代理的AOP**:Spring使用JDK动态代理或CGLIB动态代理创建目标对象的代理,代理对象在调用目标方法前后执行切面逻辑。 - **基于注解的AOP**:Spring支持在方法上直接定义切面注解,如`@Before`, `@After`, `...

    jdk1.5.0_12源代码

    通过研究这些源代码,开发者不仅可以深入了解Java语言的底层机制,还能学习到优秀的编码实践和设计模式。对于Java程序员来说,深入理解JDK的源代码是提升技术水平的重要途径,也是解决实际问题的有效手段。

Global site tag (gtag.js) - Google Analytics