@Override publicsynchronized V get(){ // serialize access // re-check Supplier<V> supplier = valuesMap.get(subKey); if (supplier != this) { // something changed while we were waiting: // might be that we were replaced by a CacheValue // or were removed because of failure -> // return null to signal WeakCache.get() to retry // the loop 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; }
这里还有一个重要的方法就是 Factory.get(),该方法由 synchronized 修饰,是用于生成代理类的 class 文件的。而生成代理类的方法在 ProxyClassFactory 的 apply 里面。
@Override public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) { Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length); for (Class<?> intf : interfaces) { // ...... 省略 if (!interfaceClass.isInterface()) { thrownew IllegalArgumentException( interfaceClass.getName() + " is not an interface"); } } // ...... 省略 for (Class<?> intf : interfaces) { int flags = intf.getModifiers(); if (!Modifier.isPublic(flags)) { accessFlags = Modifier.FINAL; String name = intf.getName(); int n = name.lastIndexOf('.'); String pkg = ((n == -1) ? "" : name.substring(0, n + 1)); if (proxyPkg == null) { proxyPkg = pkg; } elseif (!pkg.equals(proxyPkg)) { thrownew IllegalArgumentException( "non-public interfaces from different packages"); } } } //...... 省略 /* * Choose a name for the proxy class to generate. */ long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num;
/* * Generate the specified proxy class. */ byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try { 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). */ thrownew IllegalArgumentException(e.toString()); } } }
在这里有几个重要的方法说下:
1 2 3 4 5 6
// 判断是否是接口,这也是为什么 JDK动态代理必须实现一个接口了,因为不是接口的话这个地方验证过不去 if (!interfaceClass.isInterface()) { thrownew IllegalArgumentException( interfaceClass.getName() + " is not an interface"); }
至于生成的类,可以通过生成文件来查看了。当生成完 class 文件之后,回到 Proxy.newProxyInstance 方法。
1 2 3 4 5 6 7 8 9 10 11
final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run(){ cons.setAccessible(true); returnnull; } }); } return cons.newInstance(new Object[]{h});