zoukankan      html  css  js  c++  java
  • 动态代理源码分析(3)

    分析入口:

    Proxy类的newProxyInstance方法:

    @CallerSensitive
        public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h) throws IllegalArgumentException {
           //判断参数InvocationHandler(里面的invoke方法执行具体的代理逻辑)是否为空,空抛异常
            Objects.requireNonNull(h);
            //复制一份代理类需要实现的接口(和被代理类实现的接口一样)
            final Class<?>[] intfs = interfaces.clone();
            //检查是否有权限进行反射代理
            final SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
            }
            /**
             * 查看或者生成一个代理类(代理类缓存在内存中,如果之前已经有过同样类加载器和同样接口参数生成的代理类,
             * 则会缓存在内存中,此时直接返回代理类;如果缓存中没有相应代理类或者代理类已经过期失效,则根据条件生成
             * 新的代理类,放入缓存,并返回代理对象)
             */
            Class<?> cl = getProxyClass0(loader, intfs);
    
            try {
                //检查返回的代理类的权限
                if (sm != null) {
                    checkNewProxyPermission(Reflection.getCallerClass(), cl);
                }
                /**
                 * 用反射获取代理类的构造函数(根据生成代理类的源码,可知构造函数是一个有参构造,
                 * 且参数为InvocationHandler,Proxy类中定义constructorParams就是InvocationHandler)
                 */
                final Constructor<?> cons = cl.getConstructor(constructorParams);
                final InvocationHandler ih = h;
                //判断代理类的访问权限,如果不是public的权限,则做相应的设置
                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);
            }
        }

    newProxyInstance方法中调用的获取代理类Class对象的getProxyClass0方法:

    private static Class<?> getProxyClass0(ClassLoader loader,
                                               Class<?>... interfaces) {
            //如果进行动态代理时传入的代理类需要实现接口数量大于65535,则抛异常
            if (interfaces.length > 65535) {
                throw new IllegalArgumentException("interface limit exceeded");
            }
    
            /**
             * 如果在缓存中有参数loader和interfaces定义过的代理类,则简单的返回一份代
             * 理类copy否则通过ProxyClassFactory生产一个代理类
             * 
             * proxyClassCache在Proxy类内部定义:
             *      private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
             *         proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
             */
            return proxyClassCache.get(loader, interfaces);
        }
    getProxyClass0方法中调用的proxyClassCache(WeakCache<ClassLoader, Class<?>[], Class<?>>)对象分析:
    /**
     * K:动态代理参数类加载器
     * P:动态代理参数代理类需要实现的接口数组
     * V:代理类Class(当Class存在时)或者生成代理类的工厂Factory(代理类不存在时)
     */
    final class WeakCache<K, P, V> {}
    WeakCache中的属性和构造函数分析:
        private final ReferenceQueue<K> refQueue = new ReferenceQueue<>();
        /**
         * 代理类在内存中的缓存结构 :
         *      一级key是类加载器包装对象(每个类加载器可加载不同的类->代理类)
         *      二级key是接口数组
         *      value就是对应的代理类Class
         */
        private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
                = new ConcurrentHashMap<>();
        private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
                = new ConcurrentHashMap<>();
        //根据K和P生产一个二级key
        private final BiFunction<K, P, ?> subKeyFactory;
        //根据K和P生产代理类V
        private final BiFunction<K, P, V> valueFactory;
    
        /**
         * Construct an instance of {@code WeakCache}
         *
         * @param subKeyFactory a function mapping a pair of
         *                      {@code (key, parameter) -> sub-key}
         * @param valueFactory  a function mapping a pair of
         *                      {@code (key, parameter) -> value}
         * @throws NullPointerException if {@code subKeyFactory} or
         *                              {@code valueFactory} is null.
         */
        public WeakCache(BiFunction<K, P, ?> subKeyFactory,
                         BiFunction<K, P, V> valueFactory) {
            this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
            this.valueFactory = Objects.requireNonNull(valueFactory);
        }

    获取代理类Class对象的方法getProxyClass0方法中调用的proxyClassCache.get()分析(WeakCache类中的get方法):

    public V get(K key, P parameter) {
            //先判断接口数组是否为空
            Objects.requireNonNull(parameter);
            //删除失效的条目(缓存结构中失效的代理类)
            expungeStaleEntries();
            //将参数类加载器包装
            Object cacheKey = CacheKey.valueOf(key, refQueue);
    
            //懒惰式加载特定cacheKey(包装好的ClassLoader)对应的ConcurrentMap值
            ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
            //先判断cacheKey有没有对应的值,如果有,就继续执行,如果没有则进行赋值操作
            if (valuesMap == null) {
                /**
                 * map.putIfAbsent(K,V)
                 * 效果等同于:
                 * if(map.containsKey(K)){
                 *     return map.get(K);
                 * }else{
                 *     return map.put(K,V);
                 * }
                 */
                ConcurrentMap<Object, Supplier<V>> oldValuesMap
                        = map.putIfAbsent(cacheKey,
                        valuesMap = new ConcurrentHashMap<>());
                if (oldValuesMap != null) {
                    valuesMap = oldValuesMap;
                }
            }
    
            /**
             * 上述代码完成了一级key的匹配,并得到了一级key对应的值valuesMap;
             * 此处再根据类加载器和接口数组构造一个二级key,去获取相应的代理类Class
             */
            Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
            Supplier<V> supplier = valuesMap.get(subKey);
            Factory factory = null;
    
            while (true) {
                if (supplier != null) {
                    // supplier可能是一个Factory也可能是一个CacheValue<V>实例(被包装的代理类Class对象)
                    V value = supplier.get();
                    if (value != null) {
                        return value;
                    }
                }
                /**
                 * 如果supplier不是代理类Class对象,或者supplier为空;
                 * 则先将valuesMap对应中对应的代理类Class的值替换成一个
                 * 生产代理类Class的工具Factory
                 */
    
                //懒惰式加载一个生产代理类Class的工具Factory
                if (factory == null) {
                    factory = new Factory(key, parameter, subKey, valuesMap);
                }
    
                /**
                 * 一下代码都是在给valuesMap安装生产代理类Class的工具Factory
                 * 即把代理类缓存结构(key,subkey->value)中的value暂时变为Factory,
                 * 等代理类Class生产出来后,再行替换,变为真正的代理类Class缓存条目
                 */
                if (supplier == null) {
                    supplier = valuesMap.putIfAbsent(subKey, factory);
                    if (supplier == null) {
                        supplier = factory;
                    }
                } else {
                    if (valuesMap.replace(subKey, supplier, factory)) {
                        supplier = factory;
                    } else {
                        supplier = valuesMap.get(subKey);
                    }
                }
            }
        }

    get方法中调用的Factory(生产代理类Class的工具Factory:WeakCache内部类):

    private final class Factory implements Supplier<V> {
    
            private final K key;
            private final P parameter;
            private final Object subKey;
            private final ConcurrentMap<Object, Supplier<V>> valuesMap;
    
            Factory(K key, P parameter, Object subKey,
                    ConcurrentMap<Object, Supplier<V>> valuesMap) {
                this.key = key;
                this.parameter = parameter;
                this.subKey = subKey;
                this.valuesMap = valuesMap;
            }
    
            @Override
            public synchronized V get() { // serialize access
                //重复检查supplier的属性,是Factory还是真正的代理类Class
                Supplier<V> supplier = valuesMap.get(subKey);
                if (supplier != this) {
                    //如果supplier是CacheValue<V>,被包装的代理类Class对象,就返回null
                    return null;
                }
                //如果supplier是一个生产CacheValue<V>的Factory,就执行生成代码
                V value = null;
                try {
              //valueFactory.apply(key, parameter)真正生成代理类Class的代码 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); // try replacing us with CacheValue (this should always succeed) if (valuesMap.replace(subKey, this, cacheValue)) { // put also in reverseMap reverseMap.put(cacheValue, Boolean.TRUE); } else { throw new AssertionError("Should not reach here"); } // successfully replaced us with new CacheValue -> return the value // wrapped by it return value; } }

    最终获取到代理类Class后原路返回到层层调用方,实现动态代理!!!

  • 相关阅读:
    [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)
    [洛谷P1501][国家集训队]Tree II(LCT)
    [bzoj2002][Hnoi2010]Bounce 弹飞绵羊(LCT)
    Codeforces Round #683 (Div. 2, by Meet IT) E
    Codeforces Round #683 (Div. 2, by Meet IT) C
    set使用
    Educational Codeforces Round 98 (Rated for Div. 2) D
    Educational Codeforces Round 98 (Rated for Div. 2) B
    arc102a
    树状数组知识点整理二(待)
  • 原文地址:https://www.cnblogs.com/wly1-6/p/10255766.html
Copyright © 2011-2022 走看看