动态代理玩不明白?别紧张,你只是缺少这个demo( 二 )

原理
流程
获取代理类——调用Proxy.newProxyInstance获取代理类的Class实例getProxyClass0(loader, intfs)获取代理类实例的构造方法 , 并确保其访问权限final Constructor cons = cl.getConstructor(constructorParams)利用反射机制调用构造方法 , 返回代理类实例 , 参数是调用Proxy.newProxyInstance时传进来的InvocationHandler实例h。 cons.newInstance(new Object[]{h})
方法实现前面利用反射机制调用代理类的构造方法时传入了InvocationHandler实例h, 代理类$Proxy0的构造方法如下:
public $Proxy0(InvocationHandler var1) throws {super(var1);}?这是调用父类的构造函数 , 并传入参数h 。 所以在获取到代理类实例并执行方法时如测试类的subject.doSomething() , 实际调用的是代理类内的doSomething() , 如下所示 。
public final void doSomething() throws {try {super.h.invoke(this, m3, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}?所以JDK动态代理的接口方法实现逻辑是完全由InvocationHandler实例的invoke方法决定的。
获取代理类的Class实例探究
getProxyClass0(loader, intfs)方法
private static Class getProxyClass0(ClassLoader loader,Class... interfaces) {if (interfaces.length > 65535) {throw new IllegalArgumentException("interface limit exceeded");}?// If the proxy class defined by the given loader implementing// the given interfaces exists, this will simply return the cached copy;// otherwise, it will create the proxy class via the ProxyClassFactoryreturn proxyClassCache.get(loader, interfaces);}?在Proxy类getProxyClass0(loader, intfs)方法中并无核心代码 , 主要是方法最后一行去缓存对象中获取代理类实例 。
java.lang.reflect.WeakCache 类private static final WeakCache[], Class> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());?proxyClassCache是Proxy类的静态变量 , 调用WeakCache类的构造函数初始化时 , 传入keyFactory和proxyClassFactory两个实例 。 注意WeakCache对象的数据结构包含两级键值 。 接下来就进入WeakCache类的get方法查看一番 。
WeakCache类get方法代码
public V get(K key, P parameter) {Objects.requireNonNull(parameter);expungeStaleEntries();Object cacheKey = CacheKey.valueOf(key, refQueue);// lazily install the 2nd level valuesMap for the particular cacheKeyConcurrentMap> valuesMap = map.get(cacheKey);if (valuesMap == null) {ConcurrentMap> oldValuesMap= map.putIfAbsent(cacheKey,valuesMap = new ConcurrentHashMap<>());if (oldValuesMap != null) {valuesMap = oldValuesMap;}}?// create subKey and retrieve the possible Supplier stored by that// subKey from valuesMapObject subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));Supplier supplier = valuesMap.get(subKey);Factory factory = null;?while (true) {if (supplier != null) {// supplier might be a Factory or a CacheValue instanceV value = http://kandian.youth.cn/index/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 Factoryif (factory == null) {factory = new Factory(key, parameter, subKey, valuesMap);}?if (supplier == null) {supplier = valuesMap.putIfAbsent(subKey, factory);if (supplier == null) {// successfully installed Factorysupplier = factory;}// else retry with winning supplier} else {if (valuesMap.replace(subKey, supplier, factory)) {// successfully replaced// cleared CacheEntry / unsuccessful Factory// with our Factorysupplier = factory;} else {// retry with current suppliersupplier = valuesMap.get(subKey);}}}}