动态代理玩不明白?别紧张,你只是缺少这个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
- 设计模式6之代理模式
- 对微前端的11个错误认识
- 刷爆全网的动态条形图,只需5行Python代码就能实现
- 汕头世爵影音获挪威音乐之旅品牌中国(包括香港,澳门)总代理
- 从零并发框架(三)异步转同步注解+字节码增强代理实现
- HashiCorp开源Boundary:安全访问动态主机服务
- Opera GX游戏浏览器现已支持Razer Chroma RGB动态灯效
- 一位二十年老烧的经验之谈(二)
- 全息行业动态|科技让你我不再有距离
- 使用nginx反向代理github