//克隆一份 final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); }
//最终通过 supplier.get()返回对象 while (true) { if (supplier != null) { // supplier might be a Factory or a CacheValue<V> instance V value = supplier.get(); if (value != null) { return value; } }
if (factory == null) { factory = new Factory(key, parameter, subKey, valuesMap); }
if (supplier == null) { supplier = valuesMap.putIfAbsent(subKey, factory); if (supplier == null) { // successfully installed Factory supplier = factory; } // else retry with winning supplier } else { 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); } } }
//supplier.get()的实现 publicsynchronized V get(){ // serialize access Supplier<V> supplier = valuesMap.get(subKey); if (supplier != this) { returnnull; } // else still us (supplier == this)
// create new value V value = null; try { value = Objects.requireNonNull(valueFactory.apply(key, parameter)); } finally { if (value == null) { // remove us on failure 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);
// put into reverseMap reverseMap.put(cacheValue, Boolean.TRUE);
// try replacing us with CacheValue (this should always succeed) if (!valuesMap.replace(subKey, this, cacheValue)) { thrownew AssertionError("Should not reach here"); }
// successfully replaced us with new CacheValue -> return the value // wrapped by it return value; }
//·········省略部分验证代码 if (proxyPkg == null) { // if no non-public proxy interfaces, use com.sun.proxy package proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; }
/* * Choose a name for the proxy class to generate. */ long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num;