Java 动态代理实现解析

来源:互联网 发布:csol一键大跳宏编程 编辑:程序博客网 时间:2024/05/16 06:58

Java动态代理只能针对接口进行动态代理。如果需要对类进行实现代理可以使用:CGLIB,ASM等相关的操作字节码实现(在这里先只介绍下SUN 基于接口动态代理的实现)。

代码如下:

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ProxyTest {public static void main(String[] args) {/* 设置此系统属性,让JVM生成的Proxy类写入文件.保存路径为:com/sun/proxy(如果不存在请手工创建) */System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");System.out.println(Proxy.getProxyClass(IUser.class.getClassLoader(), IUser.class));IUser userImpl = (IUser) new DynamicProxy().bind(new UserImpl());System.out.println(userImpl.sayHello(" kevin LUAN"));}public static class DynamicProxy implements InvocationHandler {public Object target;public Object bind(Object target) {this.target = target;return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {return method.invoke(target, args);}}public static interface IUser {public String sayHello(String speakString);}public static class UserImpl implements IUser {@Overridepublic String sayHello(String speakString) {return "welcome " + speakString;}}}

执行结果输出:

class com.sun.proxy.$Proxy0

welcome  kevin LUAN

接下来我们去看看生成的$Proxy0.class文件。

反编译后内容如下:

package com.sun.proxy;import ProxyTest.IUser;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;public final class $Proxy0 extends Proxy  implements ProxyTest.IUser{  private static Method m1;  private static Method m3;  private static Method m0;  private static Method m2;  public $Proxy0(InvocationHandler paramInvocationHandler)    throws   {    super(paramInvocationHandler);  }  public final boolean equals(Object paramObject)    throws   {    try    {      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  public final String sayHello(String paramString)    throws   {    try    {      return (String)this.h.invoke(this, m3, new Object[] { paramString });    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  public final int hashCode()    throws   {    try    {      return ((Integer)this.h.invoke(this, m0, null)).intValue();    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  public final String toString()    throws   {    try    {      return (String)this.h.invoke(this, m2, null);    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  static  {    try    {      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });      m3 = Class.forName("ProxyTest$IUser").getMethod("sayHello", new Class[] { Class.forName("java.lang.String") });      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);      return;    }    catch (NoSuchMethodException localNoSuchMethodException)    {      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());    }    catch (ClassNotFoundException localClassNotFoundException)    {      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());    }  }}

所有生成的Proxy对象都默认继承了Proxy类,并实现了代理目标对象所实现的接口。

从代码可知,代理类做的事其实很简单,所有的方法处理都会交到:InvocationHandler来处理

2 0
原创粉丝点击