动态代理的常用实现方式是反射。
动态代理的常用实现方式是反射。
动态代理的常用实现方式是反射。

反射机制是指程序在运行期间可以访问、检测和修改其本身状态或行为的一种能力,使用反射我们可以调用任意一个类对象,以及类对象中包含的属性及方法。

1.实现方式:

  • JDK Proxy:反射
  • CGLib :CGLib 是基于 ASM(一个 Java 字节码操作框架)

2.JDK Proxy 和 CGLib 的区别

  • JDK Proxy 是 Java 语言自带的功能,无需通过加载第三方类实现;
  • Java 对 JDK Proxy 提供了稳定的支持,并且会持续的升级和更新 JDK Proxy,例如 Java 8 版本中的 - - JDK Proxy 性能相比于之前版本提升了很多;
  • JDK Proxy 是通过拦截器加反射的方式实现的;
  • JDK Proxy 只能代理继承接口的类;
  • CGLib 是第三方提供的工具,基于 ASM 实现的,性能比较高;
  • CGLib 无需通过接口来实现,它是通过实现子类的方式来完成调用的。

3.JDK Proxy 和 CGLib 的使用及代码分析

JDK Proxy

JDK Proxy 动态代理的实现无需引用第三方类,只需要实现 InvocationHandler 接口,重写 invoke() 方法即可。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*** @author fei.chen* JDK Proxy 相关示例* @date 2023/2/24下午 7:12*/
class ProxyDemo {/*** JDK Proxy*/static class JDKProxy implements InvocationHandler {private Object target; // 代理对象// 获取到代理对象public Object getInstance(Object target) {this.target = target;// 取得代理对象return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), this);}/*** 执行代理方法* @param proxy  代理对象* @param method 代理方法* @param args   方法的参数* @return* @throws InvocationTargetException* @throws IllegalAccessException*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws InvocationTargetException, IllegalAccessException {System.out.println("动态代理之前的业务处理.");Object result = method.invoke(target, args); // 执行调用方法(此方法执行前后,可以进行相关业务处理)return result;}}
}

可以看出 JDK Proxy 实现动态代理的核心是实现 Invocation 接口,我们查看 Invocation 的源码,会发现里面其实只有一个 invoke() 方法,源码如下:

public interface InvocationHandler {public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
}

这是因为在动态代理中有一个重要的角色也就是代理器,它用于统一管理被代理的对象,显然 InvocationHandler 就是这个代理器,而 invoke() 方法则是触发代理的执行方法,我们通过实现 Invocation 接口来拥有动态代理的能力。

CGLib

在使用 CGLib 之前,我们要先在项目中引入 CGLib 框架,在 pom.xml 中添加如下配置:

<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>
 /*** CGLib 代理类*/static class CGLibProxy implements MethodInterceptor {private Object target; // 代理对象public Object getInstance(Object target) {this.target = target;Enhancer enhancer = new Enhancer();// 设置父类为实例类enhancer.setSuperclass(this.target.getClass());// 回调方法enhancer.setCallback(this);// 创建代理对象return enhancer.create();}@Overridepublic Object intercept(Object o, Method method,Object[] objects, MethodProxy methodProxy) throws Throwable {Object result = methodProxy.invokeSuper(o, objects); // 执行方法调用return result;}}
// 执行 CGLib 的方法调用public static void main(String[] args) {// 创建 CGLib 代理类CGLibProxy proxy = new CGLibProxy();// 初始化代理对象MyClass myClass = (MyClass) proxy.getInstance(new MyClass());// 执行方法myClass.running();}

CGLib 在初始化被代理类时,是通过 Enhancer 对象把代理对象设置为被代理类的子类来实现动态代理的。

因此被代理类不能被关键字 final 修饰,如果被 final 修饰,再使用 Enhancer 设置父类时会报错,动态代理的构建会失败。

4.扩展

动态代理的常见使用场景有 RPC 框架的封装、AOP(面向切面编程)的实现、JDBC 的连接等。

Spring 框架中同时使用了两种动态代理 JDK Proxy 和 CGLib,当 Bean 实现了接口时,Spring 就会使用 JDK Proxy,在没有实现接口时就会使用 CGLib,我们也可以在配置中指定强制使用 CGLib,只需要在 Spring 配置中添加 <aop:aspectj-autoproxy proxy-target-class=“true”/> 即可。

【Java】动态代理原理分析相关推荐

  1. Java动态代理原理分析

    JDK动态代理原理分析 interface Foo {void foo(); }class Target implements Foo {@Overridepublic void foo() {Sys ...

  2. 【java】CGLIB动态代理原理分析

    1.概述 前一篇文章介绍了CGLIB中常用的API,实际上使用了Enhancer和MethodInterceptor之后会生成代理子类,这篇文章就是分析一下CGLIB动态代理的原理. 2.CGLIB动 ...

  3. Java 动态代理原理图解 (附:2种实现方式详细对比)

    动态代理在 Java 中有着广泛的应用,例如:Spring AOP 面向切面编程,Hibernate 数据查询.以及 RPC Dubbo 远程调用等,都有非常多的实际应用@mikechen 目录 Ja ...

  4. java动态代理原理及解析

    转载自 http://blog.csdn.net/scplove/article/details/52451899 代理:设计模式 代理模式是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制 ...

  5. java动态代理原理

    代理:设计模式 代理模式是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个真实对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 通过 ...

  6. Java 动态代理机制分析及扩展--转

    http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...

  7. Java 动态代理机制分析及扩展,第 1 部分

    引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...

  8. Java 动态代理机制分析及扩展

    简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java 动态代理运作过程,希望能帮助读者加深对 Java 动 ...

  9. Java动态代理全面分析

    代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1  主题:规定代理类和真实对象共同对外暴露的接口: 2  代理类:专门代理真实对象的类: 3 ...

  10. java动态代理原理解析

    总结:一.应用:1.要代理的类必须有对应实现接口.2.被增强的代码要实现invocationHandle接口,实现接口的invoke方法,在方法里添加增强代码和通过调用method.invoke( p ...

最新文章

  1. [转载]IPMSG(飞鸽传书)协议翻译
  2. java 范型 约束
  3. python turtle画彩虹-Python turtle 绘制彩色螺旋线
  4. flink1.12在ubuntu下面的编译记录(转载+自己整理)
  5. git clone 指定分支的内容
  6. 新手学java还是python知乎_编程初学者应该先学C++、Java还是Python?
  7. jenkins搭建_如何搭建移动端自动化测试平台?没错,就用Jenkins!
  8. 高仿小红书引导页实现效果
  9. android 系统(155)---如何自己添加号码归属地数据库?
  10. JavaScript创建对象:深入理解编程原理
  11. 个人java学习心得总结
  12. java对接快递鸟单号查询自动识别api接口,调用代码示例
  13. 【二】[详细]针孔相机模型、相机镜头畸变模型、相机标定与OpenCV实现
  14. for in在python中什么意思_Python for 循环中 in 关键字含义是什么?
  15. ​奥运赛事,斩获的不止是金银
  16. (一)软件开发背景 - 天津市政府采购中心网
  17. 腾讯大王卡、天王卡代申请
  18. PNAS:大脑区域间耦合的增加和减少会相应增加和减少人类大脑中的振荡活动
  19. 【离散数学】 SEU - 29 - 2021/06/16 - Review (in Chinese)
  20. 目标检测的Tricks | 【Trick5】学习率调优方法——warmup

热门文章

  1. 《WinForm开发系列之控件篇》Item2 BindingNavigator
  2. 自学CTP客户端开发记录001
  3. 小米公司2021秋招面试题目整理
  4. Java新手学习指南(2020最新推荐版)
  5. localhost 拒绝了我们的连接请求。Swagger
  6. 计算机老师 杂事多,有人说,老师忙,都忙在了教学之外的杂事上。你怎么看?...
  7. 小白也学得会!Python编程超简单方法算圆周率
  8. 90-95年CPU功耗感知调度研究
  9. nrm 切换不同的源工具
  10. unity硬件接入(一)---Joystick