Proxy創建代理對象源碼解析(jdk1.8)

jdk代理和cglib代理動態代理的重要實現,今天就學習一下交流一下jdk代理

  @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

		//克隆該接口
        final Class<?>[] intfs = interfaces.clone();
		//獲取系統安全接口  
		//返回:
		//如果已經爲當前應用程序建立了安全管理器,則返回此安全管理器;否則,返回 null。
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
			//檢查創建代理類所需要的權限
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * Look up or generate the designated proxy class.
         */
		 //獲取代理對象的字節碼對象
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
		 //運行構造函數
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
			//獲取構造函數
            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);
                        return null;
                    }
                });
            }
	    //返回代理對象
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

從上述源碼可以看出最重要的是獲取代理對象的字節碼對象 

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 ProxyClassFactory
		/**
		*如果代理類被實現了給定且存在的接口的類加載器定義將會返回簡單的緩存備份
		*否則將會通過代理工廠創建代理對象
		*/
        return proxyClassCache.get(loader, interfaces);
    }
  public V get(K key, P parameter) {
		//檢查指定類型的對象引用不爲空null。當參數爲null時,拋出空指針異常。
        Objects.requireNonNull(parameter);
		//清除過期的緩存
        expungeStaleEntries();
		//將ClassLoader包裝成CacheKey, 作爲一級緩存的key
        Object cacheKey = CacheKey.valueOf(key, refQueue);

        // lazily install the 2nd level valuesMap for the particular cacheKey
		////獲取得到二級緩存
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
		//沒有獲取到對應的值
        if (valuesMap == null) {
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }

        // create subKey and retrieve the possible Supplier<V> stored by that
        // subKey from valuesMap
		//根據代理類實現的接口數組來生成二級緩存key
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
		//通過subKey獲取二級緩存值
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;
        ///這個循環提供了輪詢機制, 如果條件爲假就繼續重試直到條件爲真爲止
        while (true) {
			//如果通過subKey取出來的值不爲空
			if (supplier != null) {
				// supplier might be a Factory or a CacheValue<V> instance
				//在這裏supplier可能是一個Factory也可能會是一個CacheValue
				//在這裏不作判斷, 而是在Supplier實現類的get方法裏面進行驗證
				V value = 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 Factory
			if (factory == null) {
				 //新建一個Factory實例作爲subKey對應的值
				 factory = new Factory(key, parameter, subKey, valuesMap);
			}
			if (supplier == null) {
				 //到這裏表明subKey沒有對應的值, 就將factory作爲subKey的值放入
				 supplier = valuesMap.putIfAbsent(subKey, factory);
				 if (supplier == null) {
					 // successfully installed Factory
					 //到這裏表明成功將factory放入緩存
					 supplier = factory;
				 }
				 //否則, 可能期間有其他線程修改了值, 那麼就不再繼續給subKey賦值, 而是取出來直接用
				  // else retry with winning supplier
			} else {
				 //期間可能其他線程修改了值, 那麼就將原先的值替換
				 if (valuesMap.replace(subKey, supplier, factory)) {
					 // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
					 //成功將factory替換成新的值
					 supplier = factory;
				 } else {
					 // retry with current supplier
					 //替換失敗, 繼續使用原先的值
					 supplier = valuesMap.get(subKey);
				 }
			}
        }
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章