jdk自带实现动态代理核心逻辑即是在调用 java.lang.reflect.Proxy#newProxyInstance 时,根据用户指定实现的接口动态创建一个Proxy类定义的byte[],然后调用native 的defineClass返回该代理类的实例;
核心逻辑实例:
1 String className = "com.sun.$Proxy"; 2 int accessFlags = Modifier.PUBLIC | Modifier.FINAL; 3 4 Class<?>[] cls = new Class<?>[]{Executor.class}; 5 6 byte[] bytes = ProxyGenerator.generateProxyClass(className, cls, accessFlags); 7 8 System.out.println("byteLen: " + bytes.length); 9 Path path = Paths.get("D:\misc\Proxy.class"); 10 11 try { 12 Files.createFile(path); 13 OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.WRITE); 14 outputStream.write(bytes); 15 outputStream.close(); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 }
这里将byte[] 写入文件,二进制文件Proxy.class 反编译后类似:
1 // 2 // Source code recreated from a .class file by IntelliJ IDEA 3 // (powered by Fernflower decompiler) 4 // 5 6 package com.sun; 7 8 import indi.joynic.actscase.gen.aopalliance.Executor; 9 import java.lang.reflect.InvocationHandler; 10 import java.lang.reflect.Method; 11 import java.lang.reflect.Proxy; 12 import java.lang.reflect.UndeclaredThrowableException; 13 14 public final class $Proxy extends Proxy implements Executor { 15 private static Method m1; 16 private static Method m2; 17 private static Method m3; 18 private static Method m0; 19 20 public $Proxy(InvocationHandler var1) throws { 21 super(var1); 22 } 23 24 public final boolean equals(Object var1) throws { 25 try { 26 return (Boolean)super.h.invoke(this, m1, new Object[]{var1}); 27 } catch (RuntimeException | Error var3) { 28 throw var3; 29 } catch (Throwable var4) { 30 throw new UndeclaredThrowableException(var4); 31 } 32 } 33 34 public final String toString() throws { 35 try { 36 return (String)super.h.invoke(this, m2, (Object[])null); 37 } catch (RuntimeException | Error var2) { 38 throw var2; 39 } catch (Throwable var3) { 40 throw new UndeclaredThrowableException(var3); 41 } 42 } 43 44 public final char execute() throws { 45 try { 46 return (Character)super.h.invoke(this, m3, (Object[])null); 47 } catch (RuntimeException | Error var2) { 48 throw var2; 49 } catch (Throwable var3) { 50 throw new UndeclaredThrowableException(var3); 51 } 52 } 53 54 public final int hashCode() throws { 55 try { 56 return (Integer)super.h.invoke(this, m0, (Object[])null); 57 } catch (RuntimeException | Error var2) { 58 throw var2; 59 } catch (Throwable var3) { 60 throw new UndeclaredThrowableException(var3); 61 } 62 } 63 64 static { 65 try { 66 m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object")); 67 m2 = Class.forName("java.lang.Object").getMethod("toString"); 68 m3 = Class.forName("indi.joynic.actscase.gen.aopalliance.Executor").getMethod("execute"); 69 m0 = Class.forName("java.lang.Object").getMethod("hashCode"); 70 } catch (NoSuchMethodException var2) { 71 throw new NoSuchMethodError(var2.getMessage()); 72 } catch (ClassNotFoundException var3) { 73 throw new NoClassDefFoundError(var3.getMessage()); 74 } 75 } 76 }
生成了一个新的Proxy代理子类,可以看到实际返回的类定义写入了 hashCode() 、toString()、equals()和 用户接口方法 execute(), 而且将方法调用委派给用户指定的 InvocationHandler。
所以本质上来说“动态代理”仍旧是“静态代理”,“动态”表现在不用修改代码的情况下运行时通过“魔改”,然后“偷梁换柱”的方式返回给用户代理对象;
对用户来说,调用返回的代理对象本身就实现了用户接口 (implements Executor)。
从用户的角度语义上讲即为:“塞给java.lang.reflect.Proxy任意接口和目标对象,Poxy都能给出用户指定增强目标对象接口方法逻辑的代理对象”;
如果不制定具体是哪个接口,java.lang.reflect.Proxy 无法得知在从何处抽取出接口方法生成class byte数组。
无接口AOP增强类方法就要依靠cglib之类工具了。