Proxy 1.7
以下源码分析取核心代码
1 变量定义
1 | /** prefix for all proxy class names */ |
标注代码分析:
- 定义代理类名字前缀。
- 定义弱引用,以ClassLoader loader做为key,定义一个class load 缓存。
- 为了生成代理类,初始化的cache时候,一直存在的“临时”对象。
proxyClass的缓存,key存储proxy class,value存储null,用于判断是否是代理类。
2 newProxyInstance
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
.....
/*
5. Look up or generate the designated proxy class.
*/
// #1
Class cl = getProxyClass(loader, interfaces);
/*
6. Invoke its constructor with the designated invocation handler.
*/
try {
// #2
Constructor cons = cl.getConstructor(constructorParams);
return (Object) cons.newInstance(new Object[] { h });
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
} catch (IllegalAccessException e) {
throw new InternalError(e.toString());
} catch (InstantiationException e) {
throw new InternalError(e.toString());
} catch (InvocationTargetException e) {
throw new InternalError(e.toString());
}
}生成proxy class的
$Proxy0
。- 生成
$Proxy0
的构造函数。
3 getProxyClass
1 | public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException |
标注代码分析:
- 接口数组做为缓存的key。
- proxy接口的class。
- 验证1。
- 验证2,检查
proxyClass
接口重复性,已经重复的接口不再放入interfaceNames
数组中。 - 同步
ClassLoader
缓存,查询loader的缓存集合。 - 根据
ClassLoader
查找缓存。 - cache是loader的缓存集合,同步代码块里cache获取
proxyClass
。 - 缓存对象value,此时的value,有可能是
Object(pendingGenerationMarker)
或者WeakReference
对象,后续根据不同的value值,进行不同逻辑判断。 - 因为初始化对象是
pendingGenerationMarker
,此时value对象相等,说明正在生成proxyClass
对象,进行等待,结束本次循环。 proxyClass is null
,cache初始化默认value值pendingGenerationMarker
。proxyClass
创建完毕,放入缓存。proxyClass
创建失败,清除cache中value = pendingGenerationMarker
的值。
由以上得知Java动态代理只能代理接口。
4 Other Code
1 | /** |
标注代码分析:
- 生成指定接口的
proxClass
对象。