动态代理与反射机制

一、关于反射

  • 什么是反射:
    反射机制是Java提供的一种基础功能,让程序能在运行时自省(introspect)的能力。通过反射我们能直接操作某个类或对象,甚至可以在运行时修改类定义。
  • 反射的作用:
    1、在运行时判断任意对象所属的类
    2、在运行时任意构造一个类的对象
    3、在运行时判断任意类所具有的成员变量和方法
    4、在运行时调用任意对象的方法
  • 应用场景:
    反射技术常用在各类通用框架开发中。因为为了保证框架的通用性,需要根据配置文件加载不同的对象或类,并调用不同的方法,这个时候就会用到反射——运行时动态加载需要加载的对象。
  • 特点:
    由于反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射。另外,反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

二、动态代理

  • 什么是动态代理:
    动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制。这种代理机制可以让调用者与实现者之间解耦,如进行RPC调用、框架内部的寻址、序列化、反序列化以及面向切面编程(AOP)等等。
  • 实现动态代理的方式:
    JDK自身提供的动态代理(利用反射机制)或者ASM、CGLIB(基于ASM)、Javassist等。
  • (动态)代理模式主要涉及三个要素:
    其一:抽象类接口
    其二:被代理类(具体实现抽象接口的类)
    其三:动态代理类:实际调用被代理类的方法和属性的类

三、JDK Proxy与 cglib 动态代理

JDK Proxy:
  • 举例:
    常可采用的JDK提供的动态代理接口
    InvocationHandler来实现动态代理类。其中invoke方法是该接口定义必须实现的,它完成对真实方法的调用。通过InvocationHandler接口,所有方法都由该Handler来进行处理,即所有被代理的方法都由InvocationHandler接管实际的处理任务。此外,我们常可以在invoke方法实现中增加自定义的逻辑实现,实现对被代理类的业务逻辑无侵入。
  • 局限性:
    以接口为中心,相当于添加了一种对于被调用者没有太大意义的限制。我们实例化的是 Proxy 对象,而不是真正的被调用类型,这在实践中还是可能带来各种不便和能力退化。

如果被调用者没有实现接口,而我们还是希望利用动态代理机制,那么可以考虑其他方式。我们知道 Spring AOP 支持两种模式的动态代理,JDK Proxy 或者 cglib,如果我们选择 cglib 方式,你会发现对接口的依赖被克服了。

cglib 动态代理:
  • cglib 动态代理采取的是创建目标类的子类的方式,因为是子类化,我们可以达到近似使用被调用者本身的效果。在 Spring 编程中,框架通常会处理这种情况,当然我们也可以显式指定。
JDK Proxy 的优势:
  • 最小化依赖关系,减少依赖意味着简化开发和维护,JDK 本身的支持,可能比 cglib 更加可靠。
  • 平滑进行 JDK 版本升级,而字节码类库通常需要进行更新以保证在新版 Java 上能够使用。
  • 代码实现简单。
基于类似 cglib 框架的优势:
  • 有的时候调用目标可能不便实现额外接口,从某种角度看,限定调用者实现接口是有些侵入性的实践,类似 cglib 动态代理就没有这种限制。
  • 只操作我们关心的类,而不必为其他相关类增加工作量。
  • 高性能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值