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); } @Override public 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 { @Override public 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()); } } }
从代码可知,代理类做的事其实很简单,所有的方法处理都会交到:InvocationHandler来处理