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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
| /**
* Returns the {@code java.lang.Class} object for a proxy class
* given a class loader and an array of interfaces. The proxy class
* will be defined by the specified class loader and will implement
* all of the supplied interfaces. If any of the given interfaces
* is non-public, the proxy class will be non-public. If a proxy class
* for the same permutation of interfaces has already been defined by the
* class loader, then the existing proxy class will be returned; otherwise,
* a proxy class for those interfaces will be generated dynamically
* and defined by the class loader.
*
* <p>There are several restrictions on the parameters that may be
* passed to {@code Proxy.getProxyClass}:
*
* <ul>
* <li>All of the {@code Class} objects in the
* {@code interfaces} array must represent interfaces, not
* classes or primitive types.
*
* <li>No two elements in the {@code interfaces} array may
* refer to identical {@code Class} objects.
*
* <li>All of the interface types must be visible by name through the
* specified class loader. In other words, for class loader
* {@code cl} and every interface {@code i}, the following
* expression must be true:
* <pre>
* Class.forName(i.getName(), false, cl) == i
* </pre>
*
* <li>All non-public interfaces must be in the same package;
* otherwise, it would not be possible for the proxy class to
* implement all of the interfaces, regardless of what package it is
* defined in.
*
* <li>For any set of member methods of the specified interfaces
* that have the same signature:
* <ul>
* <li>If the return type of any of the methods is a primitive
* type or void, then all of the methods must have that same
* return type.
* <li>Otherwise, one of the methods must have a return type that
* is assignable to all of the return types of the rest of the
* methods.
* </ul>
*
* <li>The resulting proxy class must not exceed any limits imposed
* on classes by the virtual machine. For example, the VM may limit
* the number of interfaces that a class may implement to 65535; in
* that case, the size of the {@code interfaces} array must not
* exceed 65535.
* </ul>
*
* <p>If any of these restrictions are violated,
* {@code Proxy.getProxyClass} will throw an
* {@code IllegalArgumentException}. If the {@code interfaces}
* array argument or any of its elements are {@code null}, a
* {@code NullPointerException} will be thrown.
*
* <p>Note that the order of the specified proxy interfaces is
* significant: two requests for a proxy class with the same combination
* of interfaces but in a different order will result in two distinct
* proxy classes.
*
*/
/**
* 得到代理类,不存在则动态生成
* @param loader 代理类所属 ClassLoader
* @param interfaces 代理类需要实现的接口
* @return
*/
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 代理类类对象
Class proxyClass = null;
/* collect interface names to use as key for proxy class cache */
String[] interfaceNames = new String[interfaces.length];
Set interfaceSet = new HashSet(); // for detecting duplicates
/**
* 入参 interfaces 检验,包含三部分
* (1)是否在入参指定的 ClassLoader 内
* (2)是否是 Interface
* (3)interfaces 中是否有重复
*/
for (int i = 0; i < interfaces.length; i++) {
String interfaceName = interfaces[i].getName();
Class interfaceClass = null;
try {
interfaceClass = Class.forName(interfaceName, false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != interfaces[i]) {
throw new IllegalArgumentException(
interfaces[i] + " is not visible from class loader");
}
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
if (interfaceSet.contains(interfaceClass)) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
interfaceSet.add(interfaceClass);
interfaceNames[i] = interfaceName;
}
// 以接口名对应的 List 作为缓存的 key
Object key = Arrays.asList(interfaceNames);
/*
* loaderToCache 是个双层的 Map
* 第一层 key 为 ClassLoader,第二层 key 为 上面的 List,value 为代理类的弱引用
*/
Map cache;
synchronized (loaderToCache) {
cache = (Map) loaderToCache.get(loader);
if (cache == null) {
cache = new HashMap();
loaderToCache.put(loader, cache);
}
}
/*
* 以上面的接口名对应的 List 为 key 查找代理类,如果结果为:
* (1) 弱引用,表示代理类已经在缓存中
* (2) pendingGenerationMarker 对象,表示代理类正在生成中,等待生成完成通知。
* (3) null 表示不在缓存中且没有开始生成,添加标记到缓存中,继续生成代理类
*/
synchronized (cache) {
do {
Object value = cache.get(key);
if (value instanceof Reference) {
proxyClass = (Class) ((Reference) value).get();
}
if (proxyClass != null) {
// proxy class already generated: return it
return proxyClass;
} else if (value == pendingGenerationMarker) {
// proxy class being generated: wait for it
try {
cache.wait();
} catch (InterruptedException e) {
}
continue;
} else {
cache.put(key, pendingGenerationMarker);
break;
}
} while (true);
}
try {
String proxyPkg = null; // package to define proxy class in
/*
* 如果 interfaces 中存在非 public 的接口,则所有非 public 接口必须在同一包下面,后续生成的代理类也会在该包下面
*/
for (int i = 0; i < interfaces.length; i++) {
int flags = interfaces[i].getModifiers();
if (!Modifier.isPublic(flags)) {
String name = interfaces[i].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,
proxyPkg = ""; // use the unnamed package
}
{
// 得到代理类的类名,jdk 1.6 版本中缺少对这个生成类已经存在的处理。
long num;
synchronized (nextUniqueNumberLock) {
num = nextUniqueNumber++;
}
String proxyName = proxyPkg + proxyClassNamePrefix + num;
// 动态生成代理类的字节码
// 最终调用 sun.misc.ProxyGenerator.generateClassFile() 得到代理类相关信息写入 DataOutputStream 实现
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces);
try {
// native 层实现,虚拟机加载代理类并返回其类对象
proxyClass = defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
// add to set of all generated proxy classes, for isProxyClass
proxyClasses.put(proxyClass, null);
} finally {
// 代理类生成成功则保存到缓存,否则从缓存中删除,然后通知等待的调用
synchronized (cache) {
if (proxyClass != null) {
cache.put(key, new WeakReference(proxyClass));
} else {
cache.remove(key);
}
cache.notifyAll();
}
}
return proxyClass;
}
|