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());
- }
- }
- }
所有生成的Proxy对象都默认继承了Proxy类,并实现了代理目标对象所实现的接口。
从代码可知,代理类做的事其实很简单,所有的方法处理都会交到:InvocationHandler来处理
转载自:http://blog.csdn.net/kevin_luan/article/details/23033673