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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章