附: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 动态代理原理图解

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

文章插图
这是因为在动态代理中有一个重要的角色,也就是代理器,它用于统一管理被代理的对象,显然 InvocationHandler 就是这个代理器 。而 invoke() 方法,则是触发代理的执行方法,我们通过实现 Invocation 接口来拥有动态代理的能力 。
CGLib 动态代理实现CGLIB (Code Generation Library) 是一个基于 ASM 的字节码生成库,它允许我们在运行时对字节码进行修改、和动态生成 CGLIB 通过继承方式实现代理 。
附:2种实现方式详细对比 Java 动态代理原理图解

文章插图
在使用 CGLib 之前,我们要先在项目中引入 CGLib 框架,在 pom.xml 中添加如下配置:
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency>
附:2种实现方式详细对比 Java 动态代理原理图解

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

文章插图
CGLib 的实现代码:
package com.mikechen.proxydemo; import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CGLibExample { static class Car {public void running() {System.out.println("The car is running.");}} /*** 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 {System.out.println("方法调用前业务处理.");Object result = methodProxy.invokeSuper(o, objects); // 执行方法调用return result;}} // 执行 CGLib 的方法调用public static void main(String[] args) {// 创建 CGLib 代理类CGLibProxy proxy = new CGLibProxy();// 初始化代理对象Car car = (Car) proxy.getInstance(new Car());// 执行方法car.running();
附:2种实现方式详细对比 Java 动态代理原理图解

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

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

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

文章插图
可以看出:
CGLib 和 JDK Proxy 的实现代码比较类似,都是通过实现代理器的接口,再调用某一个方法完成动态代理的 。

经验总结扩展阅读