JDK1.8 动态代理机制及源码解析

动态代理

a) jdk 动态代理 Proxy,
核心思想:通过实现被代理类的所有接口,生成一个字节码文件后构造一个代理对象,通过持有反射构造被代理类的一个实例,再通过invoke反射调用被代理类实例的方法,来实现代理。
缺点:被代理类必须实现一个或多个接口
参考链接:http://rejoy.iteye.com/blog/1627405
源码解析:见第四部分

cglib 动态代理

核心思想:通过生成子类字节码实现,代理类为每个委托方法都生成两个方法,以add方法为例,一个是重写的add方法,一个是CGLIB$add$0方法,该方法直接调用委托类的add方法;
底层:使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类
缺点:不能代理final修饰的类,
参考链接:http://blog.csdn.net/yakoo5/article/details/9099133/
1
2
3
4
AOP实现机制

a. 实现方式:cglib 和 jdk自带的Proxy实现
b. 策略:
1)如果是有接口声明的类进行AOP 时,spring调用的是Java.lang.reflection.Proxy 类来做处理
2)如果是没有接口声明的类时, spring通过cglib包和内部类来实现
c.配置:
<aop:aspectj-autoproxy proxy-target-class="true" />配置了这句话的话就会强制使用cglib代理。 默认就是false
1
2
3
4
5
6
JDK动态代理Demo

//业务类接口
public interface MyBusinessInterface{
public void processBusiness();
}

//业务实现类
public class MyBusinessInterfaceImpl implements MyBusinessInterface {
public void processBusiness() {
System.out.println("processing business.....");
}
}

//被代理对象调用处理程序,必须实现InvocationHandler接口
public class MyInvocationHandler implements InvocationHandler {
//所代理的真实对象
private Object target = null;
//构造器,用于传入所代理的真实对象
MyInvocationHandler(Object target){
this.target = target;
}
//需要我们实现具体业务的地方
//proxy:  所生成代理类实例
//method:  指代的是我们所要调用真实对象的某个方法的Method对象
//args:  指代的是调用真实对象某个方法时接受的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("You can do something here before process your business");
//调用目标对象的方法
Object result = method.invoke(target, args);
System.out.println("You can do something here after process your business");
//返回处理结果
return result;
}

}

//测试用例
public class Test {

public static void main(String[] args) {
//被代理真实对象
MyBusinessInterfaceImpl bpimpl = new MyBusinessInterfaceImpl();
//被代理对象调用处理程序,需传入被代理对象
MyInvocationHandler handler = new MyInvocationHandler(bpimpl);
//生成代理类实例
MyBusinessInterface bp = (MyBusinessInterface)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);
//调用processBusiness
bp.processBusiness();
}
}
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
JDK1.8动态代理源码解析

Proxy解析

//代理类
public class Proxy implements java.io.Serializable {

private static final long serialVersionUID = -2222568056686623797L;

//代理类构造函数的参数类型
private static final Class<?>[] constructorParams =
{ InvocationHandler.class };

//代理类缓存
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

//此代理实例的调用处理程序。
protected InvocationHandler h;

private Proxy() {
}

//代理类构造函数,参数类型:constructorParams所指定
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}

//获取目标代理类Class对象,需传入类加载器loader对象和被代理类实现接口数组interfaces随想
@CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)
throws IllegalArgumentException{
//拷贝接口数组
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
//校验代理类的访问问权限
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
//获取代理类Class对象
return getProxyClass0(loader, intfs);
}
//校验代理类的访问问权限,这一块比较底层,我也不明白
private static void checkProxyAccess(Class<?> caller, ClassLoader loader, Class<?>... interfaces){
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
//获取调用者类的类加载器
ClassLoader ccl = caller.getClassLoader();
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
}
//获取代理类的Clas对象
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}

//如果存在给定接口的给定装入器定义的代理类存在,则只返回缓存的副本;
//否则,它将通过proxyclassfactory创建代理类
//jdk1.8后收敛到这里 生成代理类字节码过程: ProxyClassFactory中了
return proxyClassCache.get(loader, interfaces);
}

//用于带有0个实现接口的代理类的key键值
private static final Object key0 = new Object();

/*
* Key1 and Key2 are optimized for the common use of dynamic proxies
* that implement 1 or 2 interfaces.
*/

/*
* a key used for proxy class with 1 implemented interface
*/
//用于带有1个实现接口的代理类的key键值
private static final class Key1 extends WeakReference<Class<?>> {
private final int hash;

Key1(Class<?> intf) {
super(intf);
this.hash = intf.hashCode();
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
Class<?> intf;
return this == obj ||
obj != null &&
obj.getClass() == Key1.class &&
(intf = get()) != null &&
intf == ((Key1) obj).get();
}
}

// //用于带有2个实现接口的代理类的key键值
private static final class Key2 extends WeakReference<Class<?>> {
private final int hash;
//弱引用对象:存放第二个接口类对象
private final WeakReference<Class<?>> ref2;

Key2(Class<?> intf1, Class<?> intf2) {
super(intf1);
hash = 31 * intf1.hashCode() + intf2.hashCode();
ref2 = new WeakReference<Class<?>>(intf2);
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
Class<?> intf1, intf2;
return this == obj ||
obj != null &&
obj.getClass() == Key2.class &&
(intf1 = get()) != null &&
intf1 == ((Key2) obj).get() &&
(intf2 = ref2.get()) != null &&
intf2 == ((Key2) obj).ref2.get();
}
}

// 这里用于带有>=3个实现接口的代理类的key键值(可以当实现任意数目接口的代理的key)
private static final class KeyX {
//接口数组对象的hash值
private final int hash;
//弱引用对象数组:存放表示接口的类对象数组
private final WeakReference<Class<?>>[] refs;

@SuppressWarnings("unchecked")
KeyX(Class<?>[] interfaces) {
hash = Arrays.hashCode(interfaces);
//构造一个弱引用对象数组
refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
refs[i] = new WeakReference<>(interfaces[i]);
}
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
return this == obj ||
obj != null &&
obj.getClass() == KeyX.class &&
equals(refs, ((KeyX) obj).refs);
}

private static boolean equals(WeakReference<Class<?>>[] refs1,
WeakReference<Class<?>>[] refs2) {
//长度是否相等
if (refs1.length != refs2.length) {
return false;
}
//弱引用对象数组内接口类是否相同
for (int i = 0; i < refs1.length; i++) {
Class<?> intf = refs1[i].get();
if (intf == null || intf != refs2[i].get()) {
return false;
}
}
return true;
}
}

//将接口数组映射到一个最佳键的函数,其中表示接口的类对象为弱引用。
private static final class KeyFactory
implements BiFunction<ClassLoader, Class<?>[], Object>
{
@Override
public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]); // the most frequent
case 2: return new Key2(interfaces[0], interfaces[1]);
case 0: return key0;
default: return new KeyX(interfaces);
}
}
}

//一个工厂函数生成‘给定类装载器和接口数组的代理类’。
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
//所有代理类名称的前缀
private static final String proxyClassNamePrefix = "$Proxy";

//用于生成唯一代理类名称的下一个数字
private static final AtomicLong nextUniqueNumber = new AtomicLong();

@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {

//验证intf接口类Class对象是否为给定的classloder解析的
Class<?> interfaceClass = null;
try {
//指定类加载器获取接口类class对象,
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
//验证是否为同一个接口类对象,
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
//验证类对象是否为接口
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
* 验证此接口不是副本。
*/
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
//定义代理类的包
String proxyPkg = null;
//定义代理类的修饰符:public和final类型
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

/*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
* 记录一个非公共代理接口的包,以便在同一个包中定义代理类。验证所有非公共代理接口都在同一个包中。
*/
for (Class<?> intf : interfaces) {
//获取修饰符
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) { //不是public修饰符
//则定义代理类的修饰符符:final
accessFlags = Modifier.FINAL;
//获取接口类名称,如:com.text.MyInterface
String name = intf.getName();
int n = name.lastIndexOf(‘.‘);
//获取包名,如:com.text
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
//获取包名称
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) { //interfaces含有来自不同包的非公共接口,抛错
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}

if (proxyPkg == null) {
//如果没有非公开的代理接口,使用com.sun.proxy作为包名称
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}

//选择要生成的代理类的名称。
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;

//真正生成指定的代理类字节码的地方
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//生成Calss对象
return 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());
}
}
}

//生成代理类对象
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
throws IllegalArgumentException {
//调用处理程序不能为空
Objects.requireNonNull(h);
//拷贝接口数组对象
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}

//查找或生成指定的代理类。
Class<?> cl = getProxyClass0(loader, intfs);

/*
* Invoke its constructor with the designated invocation handler.
* 调用指定的调用处理程序的构造函数
*/
try {
if (sm != null) {
//校验新代理类的权限
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//获取代理类构造函数,参数类型必须为InvocationHandler
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
//构造函数不是public,则设置当前构造函数为访问权限
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
//调用构造函数构造代理类实例,入参数为‘调用处理程序’的实例,看到这里应该就明白jdk怎么实现动态代理的吧!
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);
}
}

private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
//调用者类加载器
ClassLoader ccl = caller.getClassLoader();
//代理类的类加载器
ClassLoader pcl = proxyClass.getClassLoader();

// do permission check if the caller is in a different runtime package
// of the proxy class
//获取代理类的包名
int n = proxyClass.getName().lastIndexOf(‘.‘);
String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
//获取调用者包名
n = caller.getName().lastIndexOf(‘.‘);
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
//类加载不相同或包名不相同,校验权限
if (pcl != ccl || !pkg.equals(callerPkg)) {
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
}
}
}
}

public static boolean isProxyClass(Class<?> cl) {
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}

@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
{

//验证该对象实际上是否为上一个代理实例。
if (!isProxyClass(proxy.getClass())) {
throw new IllegalArgumentException("not a proxy instance");
}

final Proxy p = (Proxy) proxy;
final InvocationHandler ih = p.h;
if (System.getSecurityManager() != null) {
Class<?> ihClass = ih.getClass();
Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
ihClass.getClassLoader()))
{
ReflectUtil.checkPackageAccess(ihClass);
}
}

return ih;
}

private static native Class<?> defineClass0(ClassLoader loader, String name,
byte[] b, int off, int len);
}
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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
WeakCache类解析 ####

//用处存放
final class WeakCache<K, P, V> {

private final ReferenceQueue<K> refQueue = new ReferenceQueue<>();
// the key type is Object for supporting null key
//Map<类加载器,Map<接口数组对象key,代理类工厂Factory或代理类包装对象LookupValue>
private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map = new ConcurrentHashMap<>();
//存放当前key所对应的实例是否已经生成
private final ConcurrentMap<Supplier<V>, Boolean> reverseMap = new ConcurrentHashMap<>();
//生成key的工厂(对应上面的Key1-X类)
private final BiFunction<K, P, ?> subKeyFactory;
//生成value(代理类工厂,对应上面的ProxyClassFactory类)
private final BiFunction<K, P, V> valueFactory;

//构造方法,指定key和value工厂
public WeakCache(BiFunction<K, P, ?> subKeyFactory,
BiFunction<K, P, V> valueFactory) {
this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
this.valueFactory = Objects.requireNonNull(valueFactory);
}

//获取缓存值,
public V get(K key, P parameter) {
//parameter不能weinull
Objects.requireNonNull(parameter);
//删除老节点
expungeStaleEntries();

Object cacheKey = CacheKey.valueOf(key, refQueue);

// lazily install the 2nd level valuesMap for the particular cacheKey
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
if (valuesMap == null) {
//添加cacheKey - ConcurrentMap<Object, Supplier<V>对象到map中
ConcurrentMap<Object, Supplier<V>> oldValuesMap = map.putIfAbsent(cacheKey,valuesMap = new ConcurrentHashMap<>());
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}

//利用subKeyFactory生成subKey
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
//获取valuesMap中subKey所对应的值,此时为cachevalue <V>实例(步骤1:cachevalue <V>实例的来源)
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;

while (true) {
if (supplier != null) {
//步骤1:supplier可能是一个工厂对象或一个cachevalue <V>实例
V value = supplier.get();
if (value != null) {
return value;
}
}
// else no supplier in cache
// or a supplier that returned null (could be a cleared CacheValue
// or a Factory that wasn‘t successful in installing the CacheValue)

// lazily construct a Factory
if (factory == null) {
//构造一个工厂对象(步骤1:工厂对象的来源)
factory = new Factory(key, parameter, subKey, valuesMap);
}
//
if (supplier == null) {
//factory添加在valuesMap中
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// 添加成功,则factory赋值给supplier,此时supplier为一个工厂对象
supplier = factory;
}
// else retry with winning supplier
//失败则重试
} else {
//将valuesMap中subKey所对应的值替换为factory
if (valuesMap.replace(subKey, supplier, factory)) {
// successfully replaced
// cleared CacheEntry / unsuccessful Factory
// with our Factory
supplier = factory;
} else {
// retry with current supplier
supplier = valuesMap.get(subKey);
}
}
}
}

/**
* Checks whether the specified non-null value is already present in this
* {@code WeakCache}. The check is made using identity comparison regardless
* of whether value‘s class overrides {@link Object#equals} or not.
*
* @param value the non-null value to check
* @return true if given {@code value} is already cached
* @throws NullPointerException if value is null
*/
public boolean containsValue(V value) {
Objects.requireNonNull(value);

expungeStaleEntries();
return reverseMap.containsKey(new LookupValue<>(value));
}

/**
* Returns the current number of cached entries that
* can decrease over time when keys/values are GC-ed.
*/
public int size() {
expungeStaleEntries();
return reverseMap.size();
}

private void expungeStaleEntries() {
CacheKey<K> cacheKey;
while ((cacheKey = (CacheKey<K>)refQueue.poll()) != null) {
cacheKey.expungeFrom(map, reverseMap);
}
}

/**
* A factory {@link Supplier} that implements the lazy synchronized
* construction of the value and installment of it into the cache.
*/
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;

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
//校验是否为同一个
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
//在我们等待的时候,可能某些值已经被替换或则删除,返回null让WeakCache.get()再次循环获取
return null;
}
//创建一个新值
V value = null;
try {
//调用valueFactory的applay方法生成一个新值
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) { //如果生成失败,从valuesMap中删除值
valuesMap.remove(subKey, this);
}
}
// the only path to reach here is with non-null value
assert value != null;

// wrap value with CacheValue (WeakReference)
CacheValue<V> cacheValue = new CacheValue<>(value);

//尝试更换我们cachevalue(这应该总是成功的)此时
if (valuesMap.replace(subKey, this, cacheValue)) {
// 放在reversemap
reverseMap.put(cacheValue, Boolean.TRUE);
} else {
throw new AssertionError("Should not reach here");
}
//成功取代当前工厂对象为一个新的CacheValue(包裹着我们的需要对象:代理类)
return value;
}
}

//Value接口
private interface Value<V> extends Supplier<V> {}

//值对象:包裹着我们的需要对象:代理类
private static final class LookupValue<V> implements Value<V> {
private final V value;

LookupValue(V value) {
this.value = value;
}

@Override
public V get() {
return value;
}

@Override
public int hashCode() {
return System.identityHashCode(value); // compare by identity
}

@Override
public boolean equals(Object obj) {
return obj == this ||
obj instanceof Value &&
this.value == ((Value<?>) obj).get(); // compare by identity
}
}

/**
* A {@link Value} that weakly references the referent.
*/
private static final class CacheValue<V>
extends WeakReference<V> implements Value<V>
{
private final int hash;

CacheValue(V value) {
super(value);
this.hash = System.identityHashCode(value); // compare by identity
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
V value;
return obj == this ||
obj instanceof Value &&
// cleared CacheValue is only equal to itself
(value = get()) != null &&
value == ((Value<?>) obj).get(); // compare by identity
}
}

private static final class CacheKey<K> extends WeakReference<K> {

// a replacement for null keys
private static final Object NULL_KEY = new Object();

static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) {
return key == null
// null key means we can‘t weakly reference it,
// so we use a NULL_KEY singleton as cache key
? NULL_KEY
// non-null key requires wrapping with a WeakReference
: new CacheKey<>(key, refQueue);
}

private final int hash;

private CacheKey(K key, ReferenceQueue<K> refQueue) {
super(key, refQueue);
this.hash = System.identityHashCode(key); // compare by identity
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
K key;
return obj == this ||
obj != null &&
obj.getClass() == this.getClass() &&
// cleared CacheKey is only equal to itself
(key = this.get()) != null &&
// compare key by identity
key == ((CacheKey<K>) obj).get();
}

void expungeFrom(ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
ConcurrentMap<?, Boolean> reverseMap) {
// removing just by key is always safe here because after a CacheKey
// is cleared and enqueue-ed it is only equal to itself
// (see equals method)...
ConcurrentMap<?, ?> valuesMap = map.remove(this);
// remove also from reverseMap if needed
if (valuesMap != null) {
for (Object cacheValue : valuesMap.values()) {
reverseMap.remove(cacheValue);
}
}
}
}
}
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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
Proxy实际生成的代理类

import dynamic.proxy.UserService;
import java.lang.reflect.*;

public final class $Proxy11 extends Proxy
implements UserService
{

// 构造方法,参数就是刚才传过来的MyInvocationHandler类的实例
public $Proxy11(InvocationHandler invocationhandler)
{
super(invocationhandler);
}

public final boolean equals(Object obj)
{
try
{
return ((Boolean)super.h.invoke(this, m1, new Object[] {
obj
})).booleanValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}

/**
* 这个方法是关键部分
*/
public final void add()
{
try
{
// 实际上就是调用MyInvocationHandler的public Object invoke(Object proxy, Method method, Object[] args)方法,第二个问题就解决了
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}

public final int hashCode()
{
try
{
return ((Integer)super.h.invoke(this, m0, null)).intValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}

public final String toString()
{
try
{
return (String)super.h.invoke(this, m2, null);
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}

private static Method m1;
private static Method m3;
private static Method m0;
private static Method m2;

// 在静态代码块中获取了4个方法:Object中的equals方法、UserService中的add方法、Object中的hashCode方法、Object中toString方法
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
Class.forName("java.lang.Object")
});
m3 = Class.forName("dynamic.proxy.UserService").getMethod("add", 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]);
}
catch(NoSuchMethodException nosuchmethodexception)
{
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
}
catch(ClassNotFoundException classnotfoundexception)
{
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
}
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

---------------------

原文地址:https://www.cnblogs.com/ly570/p/11257593.html

时间: 2024-10-13 21:03:24

JDK1.8 动态代理机制及源码解析的相关文章

给jdk写注释系列之jdk1.6容器(1):ArrayList源码解析

原文出自吞噬天地,链接整理自ImportNew 给jdk写注释系列之jdk1.6容器(2):LinkedList源码解析 给jdk写注释系列之jdk1.6容器(3):Iterator设计模式 给jdk写注释系列之jdk1.6容器(4)-HashMap源码解析 给jdk写注释系列之jdk1.6容器(5)-LinkedHashMap源码解析 给jdk写注释系列之jdk1.6容器(6)-HashSet源码解析&Map迭代器 给jdk写注释系列之jdk1.6容器(1):ArrayList源码解析 工作中

grunt源码解析:整体运行机制&amp;grunt-cli源码解析

前端的童鞋对grunt应该不陌生,前面也陆陆续续的写了几篇grunt入门的文章.本篇文章会更进一步,对grunt的源码进行分析.文章大体内容内容如下: grunt整体设计概览 grunt-cli源码分析 grunt-cli模块概览 grunt-cli源码分析 写在后面 grunt整体设计概览 grunt主要由三部分组成.其中,grunt-cli是本文的讲解重点 grunt-cli:命令行工具,调用本地安装的grunt来运行任务,全局安装. grunt:本地grunt,一般安装在项目根目录下.主要

给jdk写注释系列之jdk1.6容器(10)-Stack&amp;Vector源码解析

前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈. 什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶,我们往木桶里放东西,往外拿东西时会发现,我们最开始放的东西在最底部,最先拿出来的是刚刚放进去的.所以,栈就是这么一种先进后出( First In Last Out,或者叫后进先出) 的容器,它只有一个口,在这个口放入元素,也在这个口取出元素. 栈最主要了两个动作就是入栈和出栈操作,其实还是很容易的明白的对不

jdk1.8ArrayList主要方法和扩容机制(源码解析)

参见博客:https://blog.csdn.net/u010890358/article/details/80515284?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task   基于jdk1.8涵盖所有方法,有些地方解释牵强不好理解. 补充博客:https://blog.csdn.net/u010250240/article/details/897629

6.Spark streaming技术内幕 : Job动态生成原理与源码解析

原创文章,转载请注明:转载自 周岳飞博客(http://www.cnblogs.com/zhouyf/) Spark streaming 程序的运行过程是将DStream的操作转化成RDD的操作,Spark Streaming 和 Spark Core 的关系如下图(图片来自spark官网) Spark Streaming 会按照程序设定的时间间隔不断动态生成Job来处理输入数据,这里的Job生成是指将Spark Streaming 的程序翻译成Spark内核的RDD操作,翻译的过程并不会触发J

Android异步消息处理机制(2)源码解析

上一章讲解了Android异步消息处理机制的基本使用,下面将简单地探寻一下异步机制背后的奥妙,源码版本为:API22. 首先,声明一下本文是在我参考了一下各位大神的文章之后才慢慢熟悉的, 若有不足之处,还望各位批评指正!.菜鸟上路,,,, 郭霖博客 鸿洋博客 刘超 深入解析android5.0系统 任玉刚博客 先后顺序按照拼音排序,无关技术本身. 先简单地总结一下Looper,MessageQueue,Message和Handler四者之间的关系: Looper和MessageQueue Loo

事件分发机制之 源码解析

事件的下发:dispatchTouchEvent ViewGroup相关事件有三个:onInterceptTouchEvent.dispatchTouchEvent.onTouchEvent View相关事件有两个:dispatchTouchEvent.onTouchEvent 简单来说就是:当一个Touch事件到达根节点时,它会依次[下发],下发的过程是调用子View的dispatchTouchEvent方法实现的. 详细来说就是:ViewGroup遍历它包含着的[子View],如果Touch

Android异步消息处理机制(4)AsyncTask源码解析

上一章我们学习了抽象类AsyncTask的基本使用(地址:http://blog.csdn.net/wangyongge85/article/details/47988569),下面我将以问答的方法分析AsyncTask源码内容,源码版本为:API22. 1. 为什么必须在UI线程实例化我们的AsyncTask,并且必须在主线程中调用execute(Params... params)? 在分析为什么在UI线程调用之前,我们先看一下实例化AsyncTask并调用execute(Params...

Android源码解析——Toast

简介 Toast是一种向用户快速提供少量信息的视图.当它显示时,它会浮在整个应用层的上面,并且不会获取到焦点.它的设计思想是能够向用户展示些信息,但又能尽量不显得唐突.本篇我们来研读一下Toast的源码,并探明它的显示及隐藏机制. 源码解析 Toast 我们从Toast的最简单调用开始,它的调用代码是: Toast.makeText(context,"Show toast",Toast.LENGTH_LONG).show(); 在上面的代码中,我们是先调用Toast的静态方法来创建一个