# proxy-demo **Repository Path**: zing173/proxy-demo ## Basic Information - **Project Name**: proxy-demo - **Description**: JDK动态代理的执行原理 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-04-22 - **Last Updated**: 2024-04-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 一、概念 ## 二、分类 1. 静态代理:编译期生成代理类 2. 动态代理:运行时动态生成代理类 1. JDK 动态代理 2. CGLIB 动态代理 ## 三、JDK动态代理的实现 ## 四、原理 ### 1、ProxyFactory - ProxyFactory 并不是代理类,它是一个代理工厂类,通过此类可以动态实例化并获取代理对象 - 代理类是程序在运行过程中动态的在内存中生成的类 - 以下代码是通过 Arthas 工具反编译得到的代理类 ```java package jdk.proxy1; import java.lang.invoke.MethodHandles; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import org.zing.proxy.test02.Performance; // 1.实现 Performance 接口 public final class $Proxy0 extends Proxy implements Performance { private static final Method m0; private static final Method m1; private static final Method m2; private static final Method m3; // 2.把我们提供了的匿名内部类对象传递给了父类 public $Proxy0(InvocationHandler invocationHandler) { super(invocationHandler); } static { ClassLoader classLoader = $Proxy0.class.getClassLoader(); try { m0 = Class.forName("java.lang.Object", false, classLoader) .getMethod("hashCode", new Class[0]); m1 = Class.forName("java.lang.Object", false, classLoader) .getMethod("equals", Class.forName("java.lang.Object", false, classLoader)); m2 = Class.forName("java.lang.Object", false, classLoader) .getMethod("toString", new Class[0]); m3 = Class.forName("org.zing.proxy.test02.Performance", false, classLoader) .getMethod("sing", Class.forName("java.lang.String", false, classLoader)); return; } catch (NoSuchMethodException noSuchMethodException) { throw new NoSuchMethodError(noSuchMethodException.getMessage()); } catch (ClassNotFoundException classNotFoundException) { throw new NoClassDefFoundError(classNotFoundException.getMessage()); } } public final boolean equals(Object object) { try { return (Boolean)this.h.invoke(this, m1, new Object[]{object}); } catch (Error | RuntimeException throwable) { throw throwable; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String toString() { try { return (String)this.h.invoke(this, m2, null); } catch (Error | RuntimeException throwable) { throw throwable; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final int hashCode() { try { return (Integer)this.h.invoke(this, m0, null); } catch (Error | RuntimeException throwable) { throw throwable; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String sing(String string) { try { return (String)this.h.invoke(this, m3, new Object[]{string}); } catch (Error | RuntimeException throwable) { throw throwable; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } private static MethodHandles.Lookup proxyClassLookup(MethodHandles.Lookup lookup) throws IllegalAccessException { if (lookup.lookupClass() == Proxy.class && lookup.hasFullPrivilegeAccess()) { return MethodHandles.lookup(); } throw new IllegalAccessException(lookup.toString()); } } ``` 从上面代码中,发现 * 代理类($Proxy0)实现了 Performance 接口,表明真实类和代理类实现同样的接口。 * 代理类($Proxy0)将我们提供了的匿名内部类对象传递给了父类。 ### 2、简化代理类的代码 ```java // 程序在运行过程中动态生成的代理类 public final class $Proxy0 extends Proxy implements Performance { // 目标对象要调用核心业务的方法 private static final Method m3; // 2.把我们提供了的匿名内部类对象传递给了父类 public $Proxy0(InvocationHandler invocationHandler) { super(invocationHandler); } static { m3 = Class.forName("org.zing.proxy.test02.Performance", false, classLoader) .getMethod("sing", Class.forName("java.lang.String", false, classLoader)); } public final String sing(String string) { return (String)this.h.invoke(this, m3, new Object[]{string}); } } ``` ### 3、JDK提供的动态代理类 ```java public class Proxy implements java.io.Serializable { protected InvocationHandler h; protected Proxy(InvocationHandler h) { this.h = h; } } ``` ### 4、代理工厂类 ```java package org.zing.proxy.test02; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 代理工厂类 - 动态创建代理对象 - 通过 Proxy.newProxyInstance 方法 创建代理对象 * * @author zqx * @date 2024-04-21 */ public class ProxyFactory { /** * 定义代理的目标对象 - 歌星 */ private final Performance target; public ProxyFactory(Performance target) { this.target = target; } /** * 获取代理对象 * * @return 代理对象 */ public Performance getProxyObject() { return (Performance) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("之前扩展:经纪人与客户谈合作,收取定金"); return method.invoke(target, args); } }); } } ``` ### 5、测试类 ```java package org.zing.proxy.test02; /** * JDK实现动态代理 * * @author zqx * @date 2024-04-21 */ public class MainTest { public static void main(String[] args) throws Exception { // 实例化目标对象 - 歌星 SingingStar singingStar = new SingingStar(); // 实例化代理对象 - 经纪人 ProxyFactory proxyFactory = new ProxyFactory(singingStar); Performance performance = proxyFactory.getProxyObject(); // 调用核心功能方法 String msg = performance.sing("月亮代表我的心"); System.out.println(msg); } } ``` **执行过程如下:** 第一:在测试类中通过代理对象调用 `sing()` 方法 第二:根据多态的特性,执行的是代理类(`$Proxy0`)中的 `sing()` 方法 第三:代理类(`$Proxy0`)中的 `sing()` 方法中又调用了 `InvocationHandler` 接口的子实现类对象的invoke方法 第四:`invoke` 方法通过反射执行了真实对象所属类(`SingingStar`)中的 `sing()` 方法