Java动态代理

Java动态代理 简要说明 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class)。
InvocationHandler
每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用 一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。我们来看看InvocationHandler这个接口的唯一一个方法 invoke 方法:

// proxy: 指代我们所代理的那个真实对象 // method: 指代的是我们所要调用真实对象的方法的Method对象 // args: 指代的是调用真实对象某个方法时接受的参数 // 返回的Object是指真实对象方法的返回类型Object invoke(Object proxy, Method method, Object[] args) throws Throwable

Proxy 【Java动态代理】Proxy这个类的作用就是用来动态创建一个代理对象
// 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 loader - the class loader to define the proxy class // 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口 interfaces - the list of interfaces for the proxy class to implement // 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 h - the invocation handler to dispatch method invocations to Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

示例 具体可参考 http://www.jianshu.com/p/e63b0685e8e
具体接口的生成类$Proxy0.class默认是不保存的,如需看到,可使用如下方法
/* 设置此系统属性,让JVM生成的Proxy类写入文件.保存路径为:com/sun/proxy(如果不存在请手工创建) */ System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

?生成的代理类$Proxy0如下
public final class $Proxy0 extends Proxy implements IPerson { private static Method m1; private static Method m3; private static Method m4; private static Method m2; private static Method m0; public $Proxy0(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 String getName() throws{ try { return (String)super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } }public final String getNameById(int var1) throws{ try { return (String)super.h.invoke(this, m4, new Object[]{Integer.valueOf(var1)}); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } }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 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.example.proxy.IPerson").getMethod("getName", new Class[0]); m4 = Class.forName("com.example.proxy.IPerson").getMethod("getNameById", new Class[]{Integer.TYPE}); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); 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()); } } }

Retrofit的动态代理实现
public T create(final Class service) { Utils.validateServiceInterface(service); if (validateEagerly) { eagerlyValidateMethods(service); } return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service }, new InvocationHandler() { private final Platform platform = Platform.get(); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // If the method is a method from Object then defer to normal invocation. if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } //Retrofit并没有将实例传递进来,而是通过注解生成具体的方法调用 //TODO 方法生成代码待分析 ServiceMethod serviceMethod = (ServiceMethod) loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall); } }); }

    推荐阅读