JDK动态代理使用(代码来自TIJ)
import sun.misc.ProxyGenerator;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Arrays;/** * Created by aiyi on 2017/3/17. */public class SimpleProxyDemo { public static void consumer(Interface iface) { iface.doSomething(); iface.somethingElse("bonobo"); } public static void main(String[] args) { RealObject realObject = new RealObject(); Interface instance = (Interface) Proxy.newProxyInstance(Interface.class.getClassLoader(), new Class[]{Interface.class}, new DynamicProxyHandler(realObject)); consumer(instance); System.out.println(instance.getClass().getName()); createProxyFile(); } private static void createProxyFile() { byte[] bytes = ProxyGenerator.generateProxyClass("ProxySubject", new Class[]{Interface.class}); FileOutputStream out = null; try { out = new FileOutputStream("ProxySubject" + ".class"); out.write(bytes); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}interface Interface { void doSomething(); void somethingElse(String arg);}class RealObject implements Interface { @Override public void doSomething() { System.out.println("doSomething"); } @Override public void somethingElse(String arg) { System.out.println("somethingElse: " + arg); }}class DynamicProxyHandler implements InvocationHandler { private Object proxied; public DynamicProxyHandler(Object proxied) { this.proxied = proxied; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("===== proxy: " + proxy.getClass() + " method: " + method + " args: " + Arrays.toString(args)); if (args != null) { for (Object arg : args) { System.out.println(arg + " "); } } return method.invoke(proxied, args); }}
声明一个代理类实现 InvocationHandler接口,实际对Interfere接口方法的调用关联到对handler的invoke方法的调用。实现类似AOP的效果
通过调用Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)方法获取通过反射生成的代理类。loader定义了获取代理类所用的类加载器,interfaces是代理类需要实现的一组接口,handler就是处理器了。
具体实现。Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)
->Proxy.getProxyClass0(ClassLoader loader, Class<?>... interfaces)
->proxyClassCache.get(loader, interfaces) //proxyClassCacahess是一个WeakCache的实例
->supplier.get() //suppiler是一个接口,其WeakCache的内部类Factory实现了这个接口
->valueFactory.apply(K t, P u) //valueFactory是WeakCache的属性,回到Proxy.java 会发现valueFactory就是ProxyClassFactory的实例
---->ProxyClassFactory.apply(K t, P u)
->ProxyGenertor.generateProxyClass
最后生成了字节码
代码生成的字节码如下
import com.aiyi.chapter14.Interface;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;public final class ProxySubject extends Proxy implements Interface { private static Method m1; private static Method m3; private static Method m2; private static Method m4; private static Method m0; public ProxySubject(InvocationHandler var1) throws { super(var1); } public final boolean equals(Object var1) throws { try { return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue(); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final void doSomething() throws { try { super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final String toString() throws { try { return (String)super.h.invoke(this, m2, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final void somethingElse(String var1) throws { try { super.h.invoke(this, m4, new Object[]{var1}); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final int hashCode() throws { try { return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue(); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")}); m3 = Class.forName("com.aiyi.chapter14.Interface").getMethod("doSomething", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); m4 = Class.forName("com.aiyi.chapter14.Interface").getMethod("somethingElse", new Class[]{Class.forName("java.lang.String")}); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } }}
可以看到方法的调用都关联到了h\*就是InvocationHandler*\.invoke()方法.那么生成的类又是怎么获得InvocationHandler的
在Proxy.newProxyInstance中有如下代码
Class cl = getProxyClass0(loader, intfs);final Constructor cons = cl.getConstructor(constructorParams);//这个h就是我们的代理类return cons.newInstance(new Object[]{h});