jdk动态代理实现例子
一 接口
二 具体实现类
三 jdk处理类
四 具体使用代码
这样我们就实现了简单的jdk动态代理,那jdk动态代理类具体是怎么生成的呢?jdk动态代理类又是怎么调用jdk处理类的invoke方法的呢?
没办法只能查看源代码了
从上可见是通过ProxyGenerator类的generateProxyClass方法产生动态代理类的字节流
那jdk动态代理类又是怎么调用jdk处理类的invoke方法的呢?看来我们要是能生成具体jdk动态代理类的字节码就好了?既然ProxyGenerator类的generateProxyClass方法能产生动态类的字节流,我们把字节流保存到文件,再通过反编译工具就能看到具体的jdk动态代理类的源代码了。
通过反编译工具得到的动态代理类源代码如下
通过查看JDK动态代理类的源代码的count方法
return ((Integer)this.h.invoke(this, m3, null)).intValue();
可见在动态代理类是直接调用注入的InvocationHandler对象的invoke方法来实现代理的
一 接口
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方法来实现代理的