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

?

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

文章插图
动态代理在 Java 中有着广泛的应用 , 例如:Spring AOP 面向切面编程,Hibernate 数据查询、以及 RPC Dubbo 远程调用等,都有非常多的实际应用@mikechen
目录
  • Java 动态代理原理
  • JDK 原生动态代理
  • CGLib 动态代理实现
  • JDK 动态代理与 CGLib 的区别
Java 动态代理原理按照代理的创建时期,代理类可以分为两种:
附:2种实现方式详细对比 Java 动态代理原理图解

文章插图
  • 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译,在程序运行前,代理类的 .class 文件就已经存在了 。
  • 动态代理:在程序运行时 , 可以运用反射机制动态创建代理类的 .class 文件 。
动态代理类与静态代理类最主要的不同点是:代理类的字节码不是在程序运行前生成的 , 而是在程序运行时再虚拟机中程序自动创建的 。
动态代理的实现方式很多 。例如:JDK 自身提供的动态代理,就利用了上面提到的反射机制 。除了反射,动态代理还可以通过 CGLib 来实现,而 CGLib 是基于 ASM(一个 Java 字节码操作框架)而非反射实现的 。
简单来说,动态代理是一种行为方式,而 反射或 ASM 只是它的一种实现手段而已 。
本文我主要详解 Java 动态代理的 2 种主流现方式:JDK 原生动态代理与 CGLib。
附:2种实现方式详细对比 Java 动态代理原理图解

文章插图
JDK 原生动态代理JDK Proxy 动态代理的实现无需引用第三方类,只需要实现 InvocationHandler 接口,重写 invoke() 方法即可,整个实现代码如下所示:、
import java.lang.reflect.InvocationHandler;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Proxy; /*** JDK Proxy 相关示例*/public class ProxyExample {static interface Car {void running();} static class Bus implements Car {@Overridepublic void running() {System.out.println("The bus is running.");}} static class Taxi implements Car {@Overridepublic void running() {System.out.println("The taxi is running.");}} /*** 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;}} public static void main(String[] args) {// 执行 JDK ProxyJDKProxy jdkProxy = new JDKProxy();Car carInstance = (Car) jdkProxy.getInstance(new Taxi());carInstance.running();
附:2种实现方式详细对比 Java 动态代理原理图解

文章插图
附:2种实现方式详细对比 Java 动态代理原理图解

文章插图
以上程序的执行结果是:
动态代理之前的业务处理 。
 The taxi is running.
附:2种实现方式详细对比 Java 动态代理原理图解

文章插图
附:2种实现方式详细对比 Java 动态代理原理图解

文章插图
可以看出,JDK Proxy 实现动态代理的核心是实现 Invocation 接口 , 我们查看 Invocation 的源码,会发现里面其实只有一个 invoke() 方法,源码如下:
public interface InvocationHandler {public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;}
附:2种实现方式详细对比 Java 动态代理原理图解

文章插图
附:2种实现方式详细对比 Java 动态代理原理图解

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

推荐阅读