Java動態代理Proxy類的解析

使用過代理的,對Proxy不會感到陌生,主要分析Proxy類的內部結構。

一、Proxy類的結構

     /**
     * a cache of proxy classes
     * 緩存java代理類
     */
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

    /**
     *  the invocation handler for this proxy instance.
     * @serial
     */
    protected InvocationHandler h;

    /**
     * Prohibits instantiation.
     */
    private Proxy() {
    }

二、Proxy類的方法
(1)public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)方法

      public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        if (h == null) {
            throw new NullPointerException();
        }
        //複製接口
        final Class<?>[] intfs = interfaces.clone();
        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 {
        //通過class獲得constructor
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            ...
            ...
            //創建代理實例
                return newInstance(cons, ih);
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString());
        }
    }

(2) private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces)
方法

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
        //從緩存中獲取,如果沒有就通過ProxyClassFactory創建
        return proxyClassCache.get(loader, interfaces);
    }

(3)proxyClassCache.get(loader,interface) 方法

public V get(K key, P parameter) {
    //省略中間的代碼
    ...
    ...
    ...
        // create subKey and retrieve the possible Supplier<V> stored by that
        // subKey from valuesMap
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
      ...
      ...
    }

(4)subKeyFactory.apply(key, parameter) 方法調用的是ProxyClassFactory@apply(ClassLoader loader, Class<?>[] interfaces) 方法

 public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            for (Class<?> intf : interfaces) {
                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                Class<?> interfaceClass = null;
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
                /*
                 * Verify that the Class object actually represents an
                 * interface.
                 */
                if (!interfaceClass.isInterface()) {
                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }
                /*
                 * Verify that this interface is not a duplicate.
                 */
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                    throw new IllegalArgumentException(
                        "repeated interface: " + interfaceClass.getName());
                }
            }
           ...
           ...
            /*
             * 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);
            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).
                 */
                throw new IllegalArgumentException(e.toString());
            }
        }
    }

以上調用過程生成代理類的過程。
更多代理相關的資料:
http://rejoy.iteye.com/blog/1627405
http://www.jianshu.com/p/6f6bb2f0ece9

發佈了298 篇原創文章 · 獲贊 9 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章