jdk动态代理实现原理

jdk动态代理实现例子

一 接口


public interface CountService {
int count();
}


二 具体实现类


public class CountServiceImpl implements CountService {

private int count = 0;

public int count() {

System.out.println("count= " + count);
return count ++;
}

}



三 jdk处理类




//jdk处理类
private static class JdkHandler implements InvocationHandler {

final Object delegate;

JdkHandler(Object delegate) {
this.delegate = delegate;
}

public Object invoke(Object object, Method method, Object[] objects)
throws Throwable
{
//System.out.println(" JDK Proxy invoke "+method.getName());
return method.invoke(delegate, objects);
}
}



四 具体使用代码



public class DynamicProxyPerformanceTest {

public static void main(String[] args) throws Exception {


CountService delegate = new CountServiceImpl();


long time = System.currentTimeMillis();


CountService jdkProxy = createJdkDynamicProxy(delegate);
time = System.currentTimeMillis()- time;
System.out.println("Create JDK Proxy: " + time + " ms");

jdkProxy.count();

byte[] bt=ProxyGenerator.generateProxyClass("Jdk$Proxy", CountServiceImpl.class.getInterfaces());


OutputStream outs=new FileOutputStream(new File("E:/Jdk$Proxy.class"));
outs.write(bt);
outs.flush();
outs.close();




}

}


这样我们就实现了简单的jdk动态代理,那jdk动态代理类具体是怎么生成的呢?jdk动态代理类又是怎么调用jdk处理类的invoke方法的呢?

没办法只能查看源代码了



public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{


/*
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces);
try {
proxyClass = defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
* class creation (such as virtual machine limitations
* exceeded).
*/
throw new IllegalArgumentException(e.toString());
}

}



从上可见是通过ProxyGenerator类的generateProxyClass方法产生动态代理类的字节流

那jdk动态代理类又是怎么调用jdk处理类的invoke方法的呢?看来我们要是能生成具体jdk动态代理类的字节码就好了?既然ProxyGenerator类的generateProxyClass方法能产生动态类的字节流,我们把字节流保存到文件,再通过反编译工具就能看到具体的jdk动态代理类的源代码了。

通过反编译工具得到的动态代理类源代码如下

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import test.kkfun.funbox.test.proxy.CountService;

public final class Jdk$Proxy extends Proxy
implements CountService
{
private static Method m1;
private static Method m3;
private static Method m0;
private static Method m2;

public Jdk$Proxy(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 (RuntimeException localRuntimeException)
{
throw localRuntimeException;
}
catch (Throwable localThrowable)
{
}
throw new UndeclaredThrowableException(localThrowable);
}

public final int count()
throws
{
try
{
return ((Integer)this.h.invoke(this, m3, null)).intValue();
}
catch (RuntimeException localRuntimeException)
{
throw localRuntimeException;
}
catch (Throwable localThrowable)
{
}
throw new UndeclaredThrowableException(localThrowable);
}

public final int hashCode()
throws
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (RuntimeException localRuntimeException)
{
throw localRuntimeException;
}
catch (Throwable localThrowable)
{
}
throw new UndeclaredThrowableException(localThrowable);
}

public final String toString()
throws
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (RuntimeException localRuntimeException)
{
throw localRuntimeException;
}
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("test.kkfun.funbox.test.proxy.CountService").getMethod("count", new Class[0]);
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());
}
}


通过查看JDK动态代理类的源代码的count方法

return ((Integer)this.h.invoke(this, m3, null)).intValue();

可见在动态代理类是直接调用注入的InvocationHandler对象的invoke方法来实现代理的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值