动态代理玩不明白?别紧张,你只是缺少这个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
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
推荐阅读
- 动态降噪+双设备连接,华为FreeBuds Pro上手评
- FlinkSQL 动态加载 UDF 实现思路
- 曹操送布局多地 代理商模式凸显优势
- 算法萌新如何学好动态规划(3)
- 大神已提取出一加8T的动态壁纸:Android 8.0+设备均可使用
- 关于边缘计算与网络动态加速
- PS5系统更新带来动态调整游戏机的风扇速度特性 以提升散热
- “会员配送费更贵”,美团外卖回应了
- Google Photos丰富Memories功能:新增循环显示图片的动态壁纸功能
- 紫米推出弯头USB-C编织线,边充边玩不挡手
