深入Java动态代理源码
背景介绍
什么是动态代理?
动态代理,本质上还是代理模式,只不过代理类是在JDK内部产生并创建实例(字节码编辑)。再者其内部还维护了一个基于弱引用的缓存结构。总结来说:动态代理 = 代理模式 + 字节码编辑 + 弱引用缓存。
我们来探究一下这个过程。
原理探究
示例代码:
public class TestProxy {
interface Hello {
void hello();
}
private static class HelloImpl implements Hello {
public void hello() {
System.out.println("hello");
}
}
public static void main(String[] args) {
Hello hello = new HelloImpl();
Class<? extends Hello> clazz = hello.getClass();
Hello proxy = (Hello)Proxy.newProxyInstance(clazz.getClassLoader(),
clazz.getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//
String name = method.getName();
if ("hello".equals(name)) {
//
System.out.println("xxx");
}
return null;
}
});
proxy.hello();
}
}
调用关系:
弱引用WeakReference
WeakCache基于弱引用的缓存结构。
构造如下:
public WeakCache(BiFunction<K, P, ?> subKeyFactory,
BiFunction<K, P, V> valueFactory) {
this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
this.valueFactory = Objects.requireNonNull(valueFactory);
}
其中的subKeyFactory为Proxy.KeyFactory;valueFactory为Proxy.ProxyClassFactory。二者都实现了BiFunction接口,简单工厂的实现。
核心数据结构:
private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
= new ConcurrentHashMap<>();
两层Map的结构:
第一层的key:CacheKey类型,继承WeakReference,使用其valueOf()创建实例(简单工厂模式)。
第一层的value:Map结构,即第二层。
第二层的key:类型可以为:Key1 Key2 KeyN 和Object(key0),不一定会继承WeakReference。通过subKeyFactory创建对象。
第二层的value:CacheValue类型,继承WeakReference,使用构造方法创建,参数为valueFactory创建的对象。
简单工厂+函数接口
Proxy.KeyFactory和Proxy.ProxyClassFactory都是简单工厂,分别用于创建key和value对象;其实现BiFunction接口,以BiFunction的apply()作为工厂的方法。
字节码编辑技术
ProxyGenerator#generateProxyClass()是基于字节码编辑技术直接产生字节码,我我们可以通过如下代码,反编译查看一下生成的class文件的源代码:
测试代码:
byte[] bytes = ProxyGenerator.generateProxyClass("xxx$Proxy", clazz.getInterfaces(), 16);
Path path = Paths.get("/Users/xwei/Desktop/Proxy.class");
try {
Files.createFile(path);
OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.WRITE);
outputStream.write(bytes);
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
反编译之后的代理类的源代码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import com.proxy.TestProxy.Hello;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
final class xxx$Proxy extends Proxy implements Hello {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public xxx$Proxy(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void hello() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("com.proxy.TestProxy$Hello").getMethod("hello");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}