Java JDK动态代理解析

来源:互联网 发布:算法的乐趣 下载 编辑:程序博客网 时间:2024/05/16 01:59

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

代码如下:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. import java.lang.reflect.InvocationHandler;  
  2. import java.lang.reflect.Method;  
  3. import java.lang.reflect.Proxy;  
  4.   
  5. public class ProxyTest {  
  6.     public static void main(String[] args) {  
  7.         /* 设置此系统属性,让JVM生成的Proxy类写入文件.保存路径为:com/sun/proxy(如果不存在请生工创建) */  
  8.         System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles""true");  
  9.         System.out.println(Proxy.getProxyClass(IUser.class.getClassLoader(), IUser.class));  
  10.         IUser userImpl = (IUser) new DynamicProxy().bind(new UserImpl());  
  11.         System.out.println(userImpl.sayHello(" kevin LUAN"));  
  12.     }  
  13.   
  14.     public static class DynamicProxy implements InvocationHandler {  
  15.         public Object target;  
  16.   
  17.         public Object bind(Object target) {  
  18.             this.target = target;  
  19.             return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);  
  20.         }  
  21.   
  22.         @Override  
  23.         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  24.             return method.invoke(target, args);  
  25.         }  
  26.     }  
  27.   
  28.     public static interface IUser {  
  29.         public String sayHello(String speakString);  
  30.     }  
  31.   
  32.     public static class UserImpl implements IUser {  
  33.   
  34.         @Override  
  35.         public String sayHello(String speakString) {  
  36.             return "welcome " + speakString;  
  37.         }  
  38.   
  39.     }  
  40. }  

执行结果输出:

class com.sun.proxy.$Proxy0

welcome  kevin LUAN

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

反编译后内容如下:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.sun.proxy;  
  2.   
  3. import ProxyTest.IUser;  
  4. import java.lang.reflect.InvocationHandler;  
  5. import java.lang.reflect.Method;  
  6. import java.lang.reflect.Proxy;  
  7. import java.lang.reflect.UndeclaredThrowableException;  
  8.   
  9. public final class $Proxy0 extends Proxy  
  10.   implements ProxyTest.IUser  
  11. {  
  12.   private static Method m1;  
  13.   private static Method m3;  
  14.   private static Method m0;  
  15.   private static Method m2;  
  16.   
  17.   public $Proxy0(InvocationHandler paramInvocationHandler)  
  18.     throws   
  19.   {  
  20.     super(paramInvocationHandler);  
  21.   }  
  22.   
  23.   public final boolean equals(Object paramObject)  
  24.     throws   
  25.   {  
  26.     try  
  27.     {  
  28.       return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();  
  29.     }  
  30.     catch (Error|RuntimeException localError)  
  31.     {  
  32.       throw localError;  
  33.     }  
  34.     catch (Throwable localThrowable)  
  35.     {  
  36.       throw new UndeclaredThrowableException(localThrowable);  
  37.     }  
  38.   }  
  39.   
  40.   public final String sayHello(String paramString)  
  41.     throws   
  42.   {  
  43.     try  
  44.     {  
  45.       return (String)this.h.invoke(this, m3, new Object[] { paramString });  
  46.     }  
  47.     catch (Error|RuntimeException localError)  
  48.     {  
  49.       throw localError;  
  50.     }  
  51.     catch (Throwable localThrowable)  
  52.     {  
  53.       throw new UndeclaredThrowableException(localThrowable);  
  54.     }  
  55.   }  
  56.   
  57.   public final int hashCode()  
  58.     throws   
  59.   {  
  60.     try  
  61.     {  
  62.       return ((Integer)this.h.invoke(this, m0, null)).intValue();  
  63.     }  
  64.     catch (Error|RuntimeException localError)  
  65.     {  
  66.       throw localError;  
  67.     }  
  68.     catch (Throwable localThrowable)  
  69.     {  
  70.       throw new UndeclaredThrowableException(localThrowable);  
  71.     }  
  72.   }  
  73.   
  74.   public final String toString()  
  75.     throws   
  76.   {  
  77.     try  
  78.     {  
  79.       return (String)this.h.invoke(this, m2, null);  
  80.     }  
  81.     catch (Error|RuntimeException localError)  
  82.     {  
  83.       throw localError;  
  84.     }  
  85.     catch (Throwable localThrowable)  
  86.     {  
  87.       throw new UndeclaredThrowableException(localThrowable);  
  88.     }  
  89.   }  
  90.   
  91.   static  
  92.   {  
  93.     try  
  94.     {  
  95.       m1 = Class.forName("java.lang.Object").getMethod("equals"new Class[] { Class.forName("java.lang.Object") });  
  96.       m3 = Class.forName("ProxyTest$IUser").getMethod("sayHello"new Class[] { Class.forName("java.lang.String") });  
  97.       m0 = Class.forName("java.lang.Object").getMethod("hashCode"new Class[0]);  
  98.       m2 = Class.forName("java.lang.Object").getMethod("toString"new Class[0]);  
  99.       return;  
  100.     }  
  101.     catch (NoSuchMethodException localNoSuchMethodException)  
  102.     {  
  103.       throw new NoSuchMethodError(localNoSuchMethodException.getMessage());  
  104.     }  
  105.     catch (ClassNotFoundException localClassNotFoundException)  
  106.     {  
  107.       throw new NoClassDefFoundError(localClassNotFoundException.getMessage());  
  108.     }  
  109.   }  
  110. }  

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

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

转载自:http://blog.csdn.net/kevin_luan/article/details/23033673

0 0