您的位置:首页 > 编程语言 > Java开发

Java JDK动态代理解析

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

代码如下:

[java] view
plaincopy





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文件。

反编译后内容如下:

[java] view
plaincopy





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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: