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();
}
}
分享到:
相关推荐
在Java编程中,代理模式是一种常用的结构型设计模式,它能提供一种在不修改原有对象的基础上,增强或扩展其功能的方式。代理模式分为静态代理和动态代理两种主要形式。 **静态代理**是程序员手动创建代理类,这个...
此外,为了确保参考资料的权威性,建议读者查阅原书《Java设计模式》以获得更加详尽的解释和说明。如果有任何意见或建议,可以通过提供的电子邮箱与作者联系。在学习设计模式的过程中,理解每一个模式的意图、结构、...
《Java设计模式》是Java开发领域的一本经典教材,由刘伟编写,深入浅出地讲解了23种GOF(GoF, Gamma, Helm, Johnson, Vlissides)设计模式,旨在提升开发者在软件设计中的灵活性和可维护性。课后习题和模拟试题是...
在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者定义“切面”,这些切面可以包含业务逻辑的某一部分,比如日志、事务管理或安全控制。切面可以在多个对象中统一地应用,提高了代码的复用性...
总结,Java动态代理是Java设计模式中的一种重要工具,它为开发者提供了在运行时扩展或增强已有对象功能的能力,是实现AOP和提高代码灵活性的有效途径。理解并熟练运用动态代理,能提升软件设计的质量和可维护性。
Java中的动态代理是一种强大的设计模式,它允许我们在运行时创建具有特定行为的代理对象,这些对象可以对原对象的方法调用进行拦截、增强或包装。Spring AOP(面向切面编程)是Spring框架的一部分,它利用了Java的...
在Java编程语言中,动态代理是一种...总结,动态代理是Java中一种强大的设计模式,通过它可以灵活地扩展对象的功能。理解其底层源码和核心思想,能够帮助开发者更有效地利用这一特性,提升代码的可维护性和可扩展性。
学生竞赛模拟-学生竞赛模拟系统-学生竞赛模拟系统源码-学生竞赛模拟管理系统-学生竞赛模拟管理系统java代码-学生竞赛模拟系统设计与实现-基于ssm的学生竞赛模拟系统-基于Web的学生竞赛模拟系统设计与实现-学生竞赛...
学生竞赛模拟-学生竞赛模拟系统-学生竞赛模拟系统源码-学生竞赛模拟管理系统-学生竞赛模拟管理系统java代码-学生竞赛模拟系统设计与实现-基于ssm的学生竞赛模拟系统-基于Web的学生竞赛模拟系统设计与实现-学生竞赛...
监听者模式,也被称为观察者模式,是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在Java中,JDK提供了内置的监听器接口和类来支持...
代理模式是一种设计模式,它是结构型模式的一种,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。代理模式的核心思想是提供一个代理类,这个代理类作为真实对象的代表,可以控制或扩展...
基于 Java 语言的浏览器设计与实现 本资源摘要信息将详细介绍基于 Java 语言的浏览器设计与实现的知识点。 1. 浏览器的设计与实现 浏览器是互联网上查找信息的重要工具,给人们提供了巨大而又宝贵的信息财富。...
总结来说,动态代理是Java中一种强大的设计模式,它通过在运行时创建代理对象,能够实现对现有对象行为的扩展和控制,极大地提高了代码的可维护性和灵活性。无论是标准库的`Proxy`类还是字节码库,都是实现这一功能...
在本项目中,我们关注的是一个名为"Java代码模拟公司置办货物系统"的应用程序。这个系统旨在模拟现实世界中的公司内部流程,特别是在购买物品时的审批和管理过程。通过这个系统,普通员工可以发起购买请求,部门经理...
- **基于代理的AOP**:Spring使用JDK动态代理或CGLIB动态代理创建目标对象的代理,代理对象在调用目标方法前后执行切面逻辑。 - **基于注解的AOP**:Spring支持在方法上直接定义切面注解,如`@Before`, `@After`, `...
通过研究这些源代码,开发者不仅可以深入了解Java语言的底层机制,还能学习到优秀的编码实践和设计模式。对于Java程序员来说,深入理解JDK的源代码是提升技术水平的重要途径,也是解决实际问题的有效手段。