JDK的动态代理
来源:互联网 发布:python爬虫培训 编辑:程序博客网 时间:2024/06/05 02:35
动态代理是Spring AOP的核心原理。以前一直停留在使用的表层认识上,这一阵子抽空研究了下。
先说下静态代理,静态代理每次只为一个类服务。而且需要为每个类编写代理类代码。动态代理的优势则在于,不用为每个代理类编写代码,而是自动根据Class的文件格式去拼装代理类的字节码。
DEMO
接口
package reflect;/** * Created by cdlvsheng on 2016/4/11. */public interface Calculator {int add(int a, int b);}
实现类
package reflect;/** * Created by cdlvsheng on 2016/4/10. */public class CalculatorImpl implements Calculator{@Overridepublic int add(int a, int b) {int result = a + b;System.out.println(String.format("%d + %d = %d", a, b, result));return result;}}
创建代理类及实现InvocationHandler接口
package reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * Created by cdlvsheng on 2016/4/11. */public class MyHandler implements InvocationHandler {private Object target;/** * 绑定委托对象并返回一个代理类 * * @param target * @return */public Object bind(Object target) {this.target = target;return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("invoke start");Object o = method.invoke(target, args);System.out.println("invoke end");return o;}}
客户端调用
package reflect;/** * Created by cdlvsheng on 2016/4/11. */public class ProxyTest {public static void main(String[] args) {MyHandler ih = new MyHandler();Calculator c = (Calculator) ih.bind(new CalculatorImpl());c.add(3, 5);}}
输出
invoke start3 + 5 = 8invoke end
动态代理类的生成依赖Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法。这个方法的第一个参数是加载新的代理类字节码的类加载器,第二个参数是代理类实现的接口。所有代理类的接口方法都将由InvocationHandler的invoke方法替代。Proxy的这个方法会调用ProxyGenerator.generateProxyClass()生成代理类的字节码byte[]数组。通过在VM的启动参数里添加如下参数,我们生成的字节数组的具体内容。
-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true
加上这个参数之后重新运行main后,我们发现项目的文件路径下多了一个$Proxy0.class类。通过反编译工具查看下这个类的内容。
//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;import reflect.Calculator;public final class $Proxy0 extends Proxy implements Calculator { private static Method m1; private static Method m0; private static Method m3; private static Method m2; public $Proxy0(InvocationHandler var1) throws { super(var1); } public final boolean equals(Object var1) throws { try { return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue(); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final int hashCode() throws { try { return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue(); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final int add(int var1, int var2) throws { try { return ((Integer)super.h.invoke(this, m3, new Object[]{Integer.valueOf(var1), Integer.valueOf(var2)})).intValue(); } catch (RuntimeException | Error var4) { throw var4; } catch (Throwable var5) { throw new UndeclaredThrowableException(var5); } } public final String toString() throws { try { return (String)super.h.invoke(this, m2, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")}); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("reflect.Calculator").getMethod("add", new Class[]{Integer.TYPE, Integer.TYPE}); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } }}
可以看处动态生成的这个$Proxy0类的add方法,其实是调用了InvocationHandler类的invoke方法。它不仅实现了Calculator类的add方法,同时实现了Object类的所有非native非static类型的方法。
这个是JDK提供的动态代理功能,它的一大劣势便是必须要求代理类实现接口。然而cglib的动态代理功能弥补了这一缺点。
1 0
- JDK的动态代理
- JDK的动态代理
- JDK的动态代理
- JDK的动态代理
- JDK的动态代理
- Jdk的动态代理
- JDK的动态代理机制
- JDK的动态代理机制
- JDK的动态代理原理
- JDK的动态代理机制
- JDK的动态代理机制
- JDK的动态代理机制
- jdk动态代理的实现
- JDK的动态代理机制
- Aop的jdk动态代理
- JDK的动态代理机制
- JDK的动态代理特性
- JDK的动态代理机制
- 关于Map英文文档的一段翻译
- 背包问题博文收藏
- leetcode——322——Coin Change
- Android - SQLite
- HDU 1232 畅通工程(Kruskal)
- JDK的动态代理
- C_银行家算法的实现
- android处理oom异常
- 【Qt】QDockWidget
- 以二叉链表的方式创建一棵二叉树,并以非递归算法中序输出;计算二叉树的繁茂度,并判断二叉树是否为完全二叉树
- blob 存储大小
- MySQL设计软件登录模块
- 第九周项目1 深复制体验(2)
- 开卷有益