开发安卓的小伙伴一定都用过 Retrofit, 那么一定也或多或少了解 Retrofit 的原理, 其中最重要的一个原理就是动态代理,那动态代理又是怎么实现的呢?这篇文章就将揭开 动态代理神秘的面纱。
动态代理快速上手
下面的例子将简单介绍如何使用动态代理:
// 定义接口
public interface ProxyInterface {
void a();
...
}
// 使用动态代理创建对象
ProxyInterface impl = (ProxyInterface) Proxy.newProxyInstance(
ProxyInterface.class.getClassLoader(),
new Class[] {ProxyInterface.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
impl.a();
动态代理源码解析
从上面的的例子我们可以看出,动态代理主要就是使用了 Proxy#newInstance
方法来创建
接口的代理实现类,那我们就从 Proxy#newInstance
方法入手,看看源码是如果实现的。
Java JDK Proxy 类源码解析
非 Android Java JDK !!!
// 代理类构造函数的参数类型
private static final Class<?>[] constructorParams = { InvocationHandler.class };
// Proxy 类的构造方法
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
public static Object newProxyInstance(
ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) throws IllegalArgumentException {
...
// 查找或者通过 ClassLoader 和接口列表生成一个继承 Proxy 类并实现了接口列表
// 的代理类的 Class
Class<?> cl = getProxyClass0(loader, intfs);
try {
...
// 获取类型的构造方法
final Constructor<?> cons = cl.getConstructor(constructorParams);
...
// 通过构造方法创建一个新的实例
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
从上面的源码我们可以简单的概括一下动态代理的原理:通过 ClassLoader 和接口列表生 成一个继承 Proxy 并实现了接口列表的代理类,然后通过反射创建一个代理类的实例。
从上面的源码中,我们不难看出 getProxyClass0
在整个动态代理起到了至关重要的作用,
所以我们继续看 getProxyClass0
是如何实现的:
// 代理 Class 的缓存
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
// Proxy#getProxyClass0
// 通过 ClassLoader 和接口列表生成一个继承 Proxy 并实现了接口列表的代理类
private static Class<?> getProxyClass0(
ClassLoader loader,
Class<?>... interfaces) {
// 检查代理类需要实现的接口数量
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 如果代理类存在直接返回一个缓存的 copy,
// 如果不存在通过 ProxyClassFactory 创建对应的代理类
return proxyClassCache.get(loader, interfaces);
}
// WeakCache 中的成员变量
private final ReferenceQueue<K> refQueue
= new ReferenceQueue<>();
// the key type is Object for supporting null key
private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
= new ConcurrentHashMap<>();
private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
= new ConcurrentHashMap<>();
private final BiFunction<K, P, ?> subKeyFactory;
private final BiFunction<K, P, V> valueFactory;
// WeakCache 的构造函数
public WeakCache(BiFunction<K, P, ?> subKeyFactory, BiFunction<K, P, V> valueFactory) {
// subKekFactory 是 Proxy 中的 KeyFactory
this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
// valueFactory 是 Proxy 汇总的 ProxyClassFactory
this.valueFactory = Objects.requireNonNull(valueFactory);
}
// WeakCache#get
// 从 cache 中获取代理,如果没有缓存择创建代理类
// key : ClassLoader
// parameters : 动态代理的接口列表
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
expungeStaleEntries();
// 通过 ClassLoader 创建 key
Object cacheKey = CacheKey.valueOf(key, refQueue);
// 如果不存在对应的 Key,则创建给 key 创建对应的 valueMap
// 这里 ValueMap 其实就是的 value 就是我们的的代理类
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
if (valuesMap == null) {
ConcurrentMap<Object, Supplier<V>> oldValuesMap
= map.putIfAbsent(cacheKey,
valuesMap = new ConcurrentHashMap<>());
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
// 通过 key 和 parameter 创建 valueMap,相当于通过 ClassLoader 和接口列表
// 生成一个唯一的 subKey
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
// 通过 subKey 获取 Supplier
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
while (true) {
// 如果 supplier 存在,直接获取 value 并返回
if (supplier != null) {
// 通过 supplier 获取代理类,这个是最重要的代码!!!
V value = supplier.get();
if (value != null) {
return value;
}
}
// 如果 supplier 不存在
// 或者 supplier#get 返回了 null(可能因为被清空的 Cache 或者 Factory
// 创建不成功)
// 创建 Factory
if (factory == null) {
// key 是 ClassLoader
// paramters 是于接口列表
// subKey 相当于 ClassLoader 和接口列表生成的唯一 key
factory = new Factory(key, parameter, subKey, valuesMap);
}
if (supplier == null) {
// 将 Factory 存入 Map 中并将返回值赋值 supplier
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// 如果 supplier 为 null,证明未曾保存 Factory
supplier = factory;
}
} else {
// 替换 factory
if (valuesMap.replace(subKey, supplier, factory)) {
// 替换成功,赋值 suppiler
// 成功是因为被清空的 CacheEntry 或者原来的 Factory 创建不成功
supplier = factory;
} else {
// 替换不成功,从 valuesMap 再此获取 suppiler, 进行再次尝试
supplier = valuesMap.get(subKey);
}
}
}
}
// 上面的源码我们知道代理类是通过 suppiler 创建的,而实际起作用的是 Factory,
// 所以我们再看看 Factory 的源码。
private final class Factory implements Supplier<V> {
private final K key;
private final P parameter;
private final Object subKey;
private final ConcurrentMap<Object, Supplier<V>> valuesMap;
// key 是 ClassLoader
// paramters 是于接口列表
// subKey 相当于 ClassLoader 和接口列表生成的唯一 key
Factory(K key, P parameter, Object subKey,
ConcurrentMap<Object, Supplier<V>> valuesMap) {
this.key = key;
this.parameter = parameter;
this.subKey = subKey;
this.valuesMap = valuesMap;
}
@Override
public synchronized V get() { // serialize access
...
V value = null;
try {
// 通过 valueFactory 创建代理类
// valueFactory 则是 Proxy 类中的 ProxyClassFactory
// key 相当于 ClassLoader
// parameter 是要代理的接口列表
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) { // remove us on failure
valuesMap.remove(subKey, this);
}
}
...
return value;
}
}
// 兜兜转转我们又回到了 Proxy 类,我们继续看看 ProxyClasFactory 是怎么实现的
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// prefix for all proxy class names
private static final String proxyClassNamePrefix = "$Proxy";
// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
...
// 通过接口列表确认代理类的包名
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
// 生成唯一的代理类名称
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
// 通过 ProxyGenerator 创建代理类的字节码!!!
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
// 通过字节码定义代理类!!!
// defineClass0 是 native 方法,这里就不展开了,能力有限
// 不过这个就很像 ClassLoader 的 defineClass 方法
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
}
到此为止,我们便可以更全面的概括动态代理的原理,通过接口列表生成继承 Proxy 类并 实现了代理接口的字节码,然后通过类似 ClassLoader#defineClass 方法定义代理类的 Class, 最后通过反射创建代理类实例。
揭开代理类字节码的庐山真面目
如何获取代理类的字节码呢?从上面的源码分析中我们不难看出,
ProxyGenerator#generateProxyClass
是生成字节码的关键,那我们就仿造源码中的写法,
生成一个代理类的字节码看看,具体代码如下:
public class ProxyDemo {
public interface ProxyInterface {
void a();
void b(String s);
String c();
String d(String s);
}
public static void main(String[] args) {
byte[] byteCode = ProxyGenerator.generateProxyClass(
"ProxyInterfaceImpl", new Class[] {ProxyInterface.class}
);
FileOutputStream out = null;
try {
out = new FileOutputStream("ProxyInterfaceImpl.class");
out.write(byteCode);
out.flush();
System.out.println("Success");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我们将字节码保存在了一个 ProxyInterfaceImpl.class 的文件中,那我我们就可以使用 javap 命令反汇编看看生成的字节码到底是什么样子的。
javap -p ProxyInterfaceImpl
下面代理类的所有成员变量:
public final class ProxyInterfaceImpl extends java.lang.reflect.Proxy implements org.paradisehell.test.ProxyDemo$ProxyInterface {
private static java.lang.reflect.Method m1;
private static java.lang.reflect.Method m4;
private static java.lang.reflect.Method m6;
private static java.lang.reflect.Method m3;
private static java.lang.reflect.Method m5;
private static java.lang.reflect.Method m2;
private static java.lang.reflect.Method m0;
...
}
可以看出代理类有 6 个 Method 类型的成员变量,不过并看不出这几个方法是什么意思, 那我们反汇编代码看看。
javap -c ProxyInterfaceImpl
下面是代理类代码反汇编的结果:
public final class ProxyInterfaceImpl extends java.lang.reflect.Proxy implements org.paradisehell.test.ProxyDemo$ProxyInterface {
// 构造方法
public ProxyInterfaceImpl(java.lang.reflect.InvocationHandler) throws ;
Code:
0: aload_0
1: aload_1
2: invokespecial #8 // Method java/lang/reflect/Proxy."<init>":(Ljava/lang/reflect/InvocationHandler;)V
5: return
// 翻译后的 Java 代码
public ProxyInterfaceImpl(InvocationHandler h) {
super.(h)
}
// equals 方法,对应 Object 中的 equals 方法
public final boolean equals(java.lang.Object) throws ;
Code:
0: aload_0
1: getfield #16 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
4: aload_0
5: getstatic #20 // Field m1:Ljava/lang/reflect/Method;
8: iconst_1
9: anewarray #22 // class java/lang/Object
12: dup
13: iconst_0
14: aload_1
15: aastore
16: invokeinterface #28, 4 // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
21: checkcast #30 // class java/lang/Boolean
24: invokevirtual #34 // Method java/lang/Boolean.booleanValue:()Z
27: ireturn
28: athrow
29: astore_2
30: new #42 // class java/lang/reflect/UndeclaredThrowableException
33: dup
34: aload_2
35: invokespecial #45 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
38: athrow
Exception table:
from to target type
0 28 28 Class java/lang/Error
0 28 28 Class java/lang/RuntimeException
0 28 29 Class java/lang/Throwable
// 翻译后的 Java 代码
public final boolean equals(Object obj) {
try {
h.invoke(this, m1, new Object[]{ obj });
} catch(Thowable t) {
throw new UndeclaredThrowableException(t.getMessage());
}
}
// 接口中定义的 d 方法
public final java.lang.String d(java.lang.String) throws ;
Code:
0: aload_0
1: getfield #16 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
4: aload_0
5: getstatic #50 // Field m4:Ljava/lang/reflect/Method;
8: iconst_1
9: anewarray #22 // class java/lang/Object
12: dup
13: iconst_0
14: aload_1
15: aastore
16: invokeinterface #28, 4 // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
21: checkcast #52 // class java/lang/String
24: areturn
25: athrow
26: astore_2
27: new #42 // class java/lang/reflect/UndeclaredThrowableException
30: dup
31: aload_2
32: invokespecial #45 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
35: athrow
Exception table:
from to target type
0 25 25 Class java/lang/Error
0 25 25 Class java/lang/RuntimeException
0 25 26 Class java/lang/Throwable
// 翻译后的 Java 代码
public final String d(String s {
try {
h.invoke(this, m4, new Object[]{ s });
} catch(Thowable t) {
throw new UndeclaredThrowableException(t.getMessage());
}
}
// 其他方法执行也是类似的,就是获取 Proxy 中的 InvocationHanlder, 然后找到当前
// 方法对应
// 接口中定义的 b 方法,其中执行的方法为 m6
...
// 接口中定义的 a 方法,其中执行的方法为 m3
...
// 接口中定义的 c 方法,其中执行的方法为 m5
...
// Object 中的 toString 方法,其中执行的方法为 m2
...
// Object 中的 hasCode 方法,其中执行的方法为 m0
...
// static 代码块
static {} throws ;
Code:
0: ldc #84 // String java.lang.Object
2: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
5: ldc #91 // String equals
7: iconst_1
8: anewarray #86 // class java/lang/Class
11: dup
12: iconst_0
13: ldc #84 // String java.lang.Object
15: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
18: aastore
19: invokevirtual #95 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
22: putstatic #20 // Field m1:Ljava/lang/reflect/Method;
25: ldc #97 // String org.paradisehell.test.ProxyDemo$ProxyInterface
27: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
30: ldc #98 // String d
32: iconst_1
33: anewarray #86 // class java/lang/Class
36: dup
37: iconst_0
38: ldc #100 // String java.lang.String
40: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
43: aastore
44: invokevirtual #95 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
47: putstatic #50 // Field m4:Ljava/lang/reflect/Method;
50: ldc #97 // String org.paradisehell.test.ProxyDemo$ProxyInterface
52: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
55: ldc #101 // String b
57: iconst_1
58: anewarray #86 // class java/lang/Class
61: dup
62: iconst_0
63: ldc #100 // String java.lang.String
65: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
68: aastore
69: invokevirtual #95 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
72: putstatic #57 // Field m6:Ljava/lang/reflect/Method;
75: ldc #97 // String org.paradisehell.test.ProxyDemo$ProxyInterface
77: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
80: ldc #102 // String a
82: iconst_0
83: anewarray #86 // class java/lang/Class
86: invokevirtual #95 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
89: putstatic #62 // Field m3:Ljava/lang/reflect/Method;
92: ldc #97 // String org.paradisehell.test.ProxyDemo$ProxyInterface
94: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
97: ldc #103 // String c
99: iconst_0
100: anewarray #86 // class java/lang/Class
103: invokevirtual #95 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
106: putstatic #67 // Field m5:Ljava/lang/reflect/Method;
109: ldc #84 // String java.lang.Object
111: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
114: ldc #104 // String toString
116: iconst_0
117: anewarray #86 // class java/lang/Class
120: invokevirtual #95 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
123: putstatic #71 // Field m2:Ljava/lang/reflect/Method;
126: ldc #84 // String java.lang.Object
128: invokestatic #90 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
131: ldc #105 // String hashCode
133: iconst_0
134: anewarray #86 // class java/lang/Class
137: invokevirtual #95 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
140: putstatic #76 // Field m0:Ljava/lang/reflect/Method;
143: return
144: astore_1
145: new #109 // class java/lang/NoSuchMethodError
148: dup
149: aload_1
150: invokevirtual #112 // Method java/lang/Throwable.getMessage:()Ljava/lang/String;
153: invokespecial #114 // Method java/lang/NoSuchMethodError."<init>":(Ljava/lang/String;)V
156: athrow
157: astore_1
158: new #118 // class java/lang/NoClassDefFoundError
161: dup
162: aload_1
163: invokevirtual #112 // Method java/lang/Throwable.getMessage:()Ljava/lang/String;
166: invokespecial #119 // Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
169: athrow
Exception table:
from to target type
0 144 144 Class java/lang/NoSuchMethodException
0 144 157 Class java/lang/ClassNotFoundException
// 翻译后的 Java 代码
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{ Object.class });
m4 = Class.forName("org.paradisehell.test.ProxyDemo$ProxyInterface").getMethod("d", new Class[]{ String.class });
m6 = Class.forName("org.paradisehell.test.ProxyDemo$ProxyInterface").getMethod("b", new Class[]{ String.class });
m3 = Class.forName("org.paradisehell.test.ProxyDemo$ProxyInterface").getMethod("a", new Class[]{});
m5 = Class.forName("org.paradisehell.test.ProxyDemo$ProxyInterface").getMethod("c", new Class[]{});
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[]{});
m0 = Class.forName("java.lang.Object").getMethod("hasCode", new Class[]{});
} catch(NoSuchMethodError e1) {
throw new NoSuchMethodError(e1.getMessage());
} catch(NoClassDefFoundError e2) {
throw new NoClassDefFoundError(e2.getMessage());
}
}
}
这下就清晰多了,通过上面的反汇编我们可以得到下面几个代理类的特征:
- 继承 Proxy
- 实现了接口方法
- 实现了 Object 的 equals, toString 和 hashCode 三个方法
最后,代理原理也很简单,就是在 static 块通过反射获取要代理的方法并保存在成员变量 中,然后在调用相关方法的时候,找到保存在成员变量中的对应的方法通过 Proxy 的 InvocationHandler 执行其 invoke 方法就完成了代理。
Android JDK Proxy 类源码解析
Android JDK Proxy 的源码和 Java JDK Proxy 的源码大同小异,主要区别在于 ProxyClassFactory 的实现:
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// prefix for all proxy class names
private static final String proxyClassNamePrefix = "$Proxy";
// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
...
// 获取代理类的包名
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
// if no non-public proxy interfaces, use the default package.
proxyPkg = "";
}
{
// Android 这里没有通过 ProxyGenerator 生成字节码
// 而是获取要代理的方法,直接生成代理类的 Class
List<Method> methods = getMethods(interfaces);
Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
validateReturnTypes(methods);
List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
Method[] methodsArray = methods.toArray(new Method[methods.size()]);
Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
/*
* Choose a name for the proxy class to generate.
*/
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
// generateProxy 为 native 方法并且方法的返回值为 class
// 参数分别是:
// proxyName : 代理类的名称(含包名)
// interfaces : 需要实现的接口列表
// loader : ClassLoader
// methodArray : 存有要代理的方法数组
// exceptionsArray: 存有异常的数组,长度和 methodArray 相等,并和方法一一对应
return generateProxy(proxyName, interfaces, loader, methodsArray,
exceptionsArray);
}
}
}
关于 gernrateProxy
是如何实现的,有兴趣的同学可以看 AOSP 的源码,这里就不展开
讲了(其实我看不懂,哈哈哈)。
下面的这两个链接是 gernrateProxy
源码的实现代码,有兴趣的同学可以看一下
(需要翻墙)。
不过可以告诉大家一个结论,C++ 代码里并没有生成对应的字节码,而是通过 C++ 中的 class 类直接设置对应的方法、接口列表、ClassLoader 等一系列参数,直接生成了对应 的代理类. 如果这里我理解有误还请大佬指出来,这里先谢谢了。
除此之外,Android 的代理类,也有类似的 m0,m1,m2,m3 的方法,大家可以自己写个例子,
通过反射获取动态代理的实例获取代理类相关的属性和方法,和 Java 版本没什么区别,只
不过 Android 生成代理类的过程都放在了 native 层,少了和 Java 层的再次交互,速度
上更快一些,我想这也是 Android JDK Proxy 的 generateProxy
方法加了 FastNative
注解的原因吧。
总结
动态代理的原理:Java 版本通过生成继承了 Proxy 并实现了接口列表的对应代理类的字节码, 然后通过 defineClass 方式定义对应的代理类, 最后通过反射创建代理对象实例;而 Android 版本直接通过方法、接口列表、ClassLoader 等参数直接生成了对应代理类, 省去了生成字节码的过程,将代理类的生成都放在了 navtive 层。
代理类的方法执行原理:代理类在 static 块通过放射讲要代理的方法保存在成员变量中,
具体方法执行的时候获取对应的方法通过 Proxy 的 InvocationHandler 的 invoke 方法
代理具体的方法,这里的 InvocationHandler 其实就是我们 Proxy#newInstance
传入的
InvocationHandler。
写在最后
使用了 Retrofit 很多年了,也知道它使用了动态代理的设计模式,不过对动态代理的原理 其实是一知半解,通过这次源码分析,算是比较彻底的搞明白的动态代理的原理,不过一个 挺要命的东西就是一碰到 native 方法就傻眼,希望在以后工作和学习中能有机会好好的研 究一下 C++ 吧,这样才算真的彻底弄明白了源码原理。最后希望这篇文章可以帮助正在学习 或者对动态代理感兴趣的你。