动态代理:JDK代理原理解析

概要

代理模式结构

  代理可分为2类对象:
  目标类:一个是真正的你要访问的对象,原来的逻辑实现者。
  代理类:一个是代理对象,从抽象层看,他包含了原来的逻辑与需要额外增加的代理/增强逻辑。
  真正对象与代理对象实现同一个接口(实际上也可能是继承Cglib),先访问代理类再访问真正要访问的对象。
  代理模式分为静态代理、动态代理。
    静态代理是由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
    动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。

代理模式抽像图与类图

概念抽象图:
  调用者只关心代理类,对代理类的调用,都将对增强类与目标类(被代理类)先后发起调用。以此达到代理或者功能增强的效果。实际操作中,jdk代理,cglib代理都把代理类拆分出一人增强类接口(增加与代理逻辑),达到代理类与增强类通过接口解耦。
  
这里写图片描述

jdk/cglib抽象流程与图:

  • 代理类:与目标类实现同一个接口(可以多个),或者代理类继承了实现类。则可对所有接口方法或者类方法进行代理。
  • 增强类:在调用目标类代理方法前后增加的逻辑处理,如安全检查;日志记录、统计;事务开启、回滚、关闭等等。一般都需要实现InvocationHandler或者MethodInterceptor接口。
  • 代理类一般持有增强类的实例,当客户调用代理类方法时,将会调用增强类方法,在增强类方法中,则做额外逻辑处理或者目标类方法的调用。
  • 代理类一般会有Method类似变量,有多少个代理方法,至少有多少个这种变量。在实际调用代理方法时,此方法可作为参数,传递给增强类的invoke/intercept方法,以便在后续通过反射调用目标类方法。
    这里写图片描述

JDK的动态代理

JDK的动态代理,就是在程序运行的过程中,根据被代理的接口来动态生成代理类的class文件,并加载运行的过程。JDK从1.3开始支持动态代理。

JDK提供了java.lang.reflect.Proxy类来实现动态代理的,可通过它的newProxyInstance来获得代理实现类。而代理逻辑的增强,则是通过实现接口java.lang.reflect.InvocationHandler来完成,它提供了一个invoke方法供实现者提供相应的代理逻辑的实现。

JDK动态代理主要逻辑描述

  1. 代理类与被代理类实现同样的接口列表,并且使用相同的类加载器。
  2. 增强类实现InvocationHandler接口,在invoke方法中完成代理增强逻辑,并于此方法中反射调用目标类的方法,故增强类也是需要持有目标类的实例的。
  3. 代理类通过Proxy类创建(通过newProxyInstance、getProxyClass方法创建)。
  4. 代理类承继了Proxy,并且通过带参构造函数InvocationHandler初始化。传入了增强类的实例到父类Proxy变量h,所以代理类持有了增强类的实例
  5. 此时,代理类持有了增强类的实例,增强类持有了目标类的实例。调用者使用代理类时,都会调用到增强类的invoke方法,并且传入了Method参数(目标类接口方法签名)。而增强类则在invoke方法中,通过持有的目标类实例与此Method参数,反射调用到目标类方法。(当前在invoke方法中,还可以做些额外的增强逻辑)至此完成了代理操作。

JDK动态代理实现类图:
这里写图片描述

关于JDK如何生成代理类的细节在此不再赘述,造重复的轮子了, 详见转载深度剖析JDK动态代理机制

下一篇:动态代理:Cglib代理原理解析


以上为个人观点,若有错误或者疏漏,欢迎指正。^_^

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值