为跳槽做打算,最近在猛学,回顾一下知识点,突然发现动态代理还是理解的模糊,狠狠研究了一天,写此文以作纪念。
首先写个普通的代理
来个接口:
public interface Drawable {
public void draw();
}
再来个实现类:
public class Pen implements Drawable {
public void draw() {
System.out.println("draw something");
}
}
代理类(随便在博客写,未经编译):
public class ProxyPen implements Drawable{
private Drawable draw;
public ProxyPen(Drawable draw){
this.draw = draw;
}
public viod draw(){
System.out.println("before draw");
draw.draw();
}
}
//接下来为调用代码
Drawable pen = new Pen();
ProxyPen proxy = new ProxyPen(pen);
proxy.draw();
以上的静态代理很简单,无非就是聚合+多态。
但是只能代理实现Drawable接口的类,显然具有很大局限性。
而动态代理顾名思义就是动态生成代理类,ProxyPen将根据参数动态生成,要让其动态生成显然必须取得代理的接口,取得接口后能实现代理类,但是代理类添加的内容却还是定死的System.out.println("before draw");这也不满足动态要求,所以代理内容必须也要能自定义,想输任何代理内容,当然还是多态,传入一个处理代理内容的接口Handler即可:
首先定义代理接口:
public interface InvocationHandler {
public void invoke(Method m,Object... args) throws Exception;
}
public class Proxy {
public static Object newProxy(Class interfaces,InvocationHandler handler) throws Exception{
String r = "\n";
Method[] methods = interfaces.getMethods();
StringBuffer sb = new StringBuffer("");
for(int i =0;i<methods.length;i++){
sb.append(" public void "+methods[i].getName()+"() {"+r+
" try{ "+r+
" Method md = "+interfaces.getName()+".class.getMethod(\""+methods[i].getName()+"\");"+r+
" handler.invoke( md,new Object[]{});"+r+
" }catch(Exception e){e.printStackTrace();}"+r+
" }"+r
);
}
String src = "package com.javaeye.aronlulu.proxy;"+r+
"import java.lang.reflect.*;"+r+
"public class ProxyPen implements "+interfaces.getName() +"{"+r+
" private com.javaeye.aronlulu.proxy.InvocationHandler handler;"+r+
" public ProxyPen("+handler.getClass().getName()+" handler){"+r+
" this.handler = handler;"+r+
" }"+r+
System.out.println(\"before\");"+r+
sb.toString()+
"}" +r;
String dir = System.getProperty("user.dir")+"/src/com/javaeye/aronlulu/proxy/";
FileWriter writer = new FileWriter(new File(dir+"ProxyPen.java"));
writer.write(src);
writer.flush();
writer.close();
//编译动态代理类
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(dir+"ProxyPen.java");
CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();
//加载并调用返回代理接口
URL[] urls = new URL[]{new URL("file:/"+dir)};
URLClassLoader loader = new URLClassLoader(urls);
Class c = loader.loadClass("com.javaeye.aronlulu.proxy.ProxyPen");
Constructor ctr = c.getConstructor(handler.getClass());
return ctr.newInstance(handler);
}
}
接下来编写具体处理代理类代码:
public class DrawHandler implements InvocationHandler {
private Object draw;
public DrawHandler (Object draw){
this.draw = draw;
}
public void invoke(Method m,Object[] args) throws Exception{
System.out.println("before");
m.invoke(draw, args);
System.out.println("after");
}
}
测试代码:
Drawable drawable = new Pen();
InvocationHandler handler = new DrawHandler(drawable);
Drawable draw = (Drawable) Proxy.newProxy(Drawable.class,handler);
draw.draw();
动态代理的实现简单完成了,当然跟java的动态代理实现没法比,中间还封装了很多类型检查及反射实现。动态代理原理其实无非就是反射+多态+聚合的实现,当然有了动态代理,很多强大的功能就能实现了,最有名的无非就是AOP,java动态代理的局限性是只能针对接口,若要针对具体业务类,则需要CGLIB这样的第三方框架了,springAOP则采用了以上两种组合,默认还是使用java动态代理,设置Bean中一个属性开关来控制,若非接口实现,则开始调用CGLIB。
分享到:
相关推荐
Java动态代理是Java编程中一个非常重要的特性,它允许我们在运行时创建代理对象,这些代理对象可以代替原对象执行某些额外的操作,而无需修改原对象的代码。动态代理在AOP(面向切面编程)中广泛应用,如日志记录、...
#### 二、Java动态代理原理 Java动态代理的核心类主要有两个:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。 1. **Proxy**:这是一个工具类,用于创建一个实现了一组给定接口的动态代理...
Java动态代理是Java编程中的一种重要技术,它允许我们在运行时创建对象的代理,以便在调用实际对象的方法之前和之后执行额外的操作。本资源包专注于CGLIB库,一个强大的代码生成库,用于实现Java动态代理。 CGLIB...
Java动态代理是Java提供的一种在运行时创建代理对象的技术,它是实现类似Spring AOP(面向切面编程)功能的关键机制之一。...但是,理解Java动态代理的底层原理对于深入理解Spring AOP的工作方式是非常有益的。
在Java编程中,动态代理是一种强大的特性,它允许我们在运行时创建代理类,这些代理类可以代表或增强原始目标类的行为。在这个名为"Java动态代理ReflectProxyDemo"的示例中,我们将深入探讨如何利用Java的反射API和...
### 一、Java动态代理原理 Java中的动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。`Proxy`类用于生成动态代理类的实例,而`InvocationHandler`接口则定义了代理...
Java反射和动态代理是Java编程中的重要特性,它们允许程序在运行时检查和操作类、接口、对象等的内部结构,以及动态地创建代理对象来处理特定任务。在这篇文章中,我们将深入探讨这两个主题,结合"reflections"这个...
本文将深入探讨Java动态代理的基本概念、工作原理以及如何使用。 ### 1. JDK动态代理 JDK动态代理是Java标准库中提供的一种机制,位于`java.lang.reflect`包下。它通过实现`java.lang.reflect.InvocationHandler`...
### Java的动态代理知识点解析 #### 一、概念与背景 Java动态代理是一种常见的面向切面编程(AOP)技术的应用,它允许我们在不修改现有代码的基础上增加新的功能或行为。这种技术广泛应用于日志记录、性能监控、事务...
在Java编程中,动态代理(Dynamic Proxy)是一种强大的设计模式,它允许我们在运行时创建具有特定接口的新对象。Java的动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口...
要进行模拟,首先需要了解CGLIB代理的核心实现原理,包括代理类的生成、方法拦截和回调机制等。 1. 代理类的生成 CGLIB使用Enhancer类来生成代理对象。Enhancer的工作原理是对指定的目标类进行字节码增强,并创建该...
在这个“狗星例子”中,我们将深入理解Java动态代理的工作原理,并通过具体的代码示例来阐述其核心概念。 首先,我们要知道Java动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect....
通过模拟其内部实现,我们可以更深入地理解动态代理的工作原理,并根据需求定制自己的代理机制。通过阅读和分析提供的代码文件(3-1代码、3-2代码、3-3代码),我们可以看到具体的实现细节,如方法的调用链路、参数...
这篇博文“利用java反射、注解及泛型模拟ORM实现”旨在探讨如何结合这三种技术来实现对象关系映射(ORM),这是一种将数据库表与Java对象之间进行绑定的技术,简化了数据操作。 首先,我们来理解一下这三个概念: ...
Java动态代理是Java编程中一个重要的特性,它允许我们在运行时创建代理类,这些代理类可以作为原有类的代理,实现在调用原有方法前后添加额外的功能,如日志记录、性能统计、事务处理等。动态代理在设计模式中对应的...
总的来说,通过Java的动态代理模拟Spring AOP可以帮助我们理解AOP的基本原理,并在实际项目中实现一些简单的切面逻辑。然而,对于更复杂的需求,如跨越多个方法的事务管理,Spring AOP提供了更全面的解决方案。熟悉...
Java动态代理是Java编程中一个非常重要的特性,它允许我们在运行时创建代理对象来扩展或增强已有对象的功能。动态代理通常用于实现AOP(面向切面编程)和RPC(远程过程调用)等场景,为代码提供事务管理、日志记录、...
在Java编程中,JDK动态代理是一种非常重要的技术,它允许我们在运行时创建对现有接口的代理实现。这种技术在很多场景下都有广泛的应用,比如AOP(面向切面编程)、事务管理、缓存处理等。现在我们来深入探讨一下JDK...
本教程涵盖了Java动态代理的基本原理和使用,以及Java 8的重要新特性,包括Lambda表达式、方法引用、Stream API和日期时间API。同时,介绍了AOP的概念及其在Spring框架中的应用。通过学习这些内容,开发者可以更好地...