设为首页 加入收藏

TOP

时隔多年,这次我终于把动态代理的源码翻了个地儿朝天(三)
2023-07-25 21:44:05 】 浏览:127
Tags:时隔多 终于把
eyFactory; private final BiFunction<K, P, V> valueFactory; // 构造方法 public WeakCache(BiFunction<K, P, ?> subKeyFactory, BiFunction<K, P, V> valueFactory) { this.subKeyFactory = Objects.requireNonNull(subKeyFactory); this.valueFactory = Objects.requireNonNull(valueFactory); } //核心入口方法 我们接下来介绍这个类 public V get(K key, P parameter) { } ...

上面的源代码中写明,代理对象的核心方法是get , 我们结合上下文 发现 key是loader 类加载器,parameter是接口数组interfaces

5、proxyClassCache.get

这个对象是从缓存中获取字节码对象,key是接口,value是对象的字节码文件,如果给定的接口存在则返回字节码文件,如果不存在则调用proxyClassFactory创建代理类进行创建

/**
     * return proxyClassCache.get(loader, interfaces);
     * <p>
     * 获取代理对象的核心方法
     *
     * @param key       类加载器 loader
     * @param parameter 接口的数组 interfaces
     * @return
     */
    public V get(K key, P parameter) {
        //接口数组不能为空,否则抛出异常
        Objects.requireNonNull(parameter);
        // 删除过时的条目
        expungeStaleEntries();
        // 生成缓存key对象实例,如果key = null,cacheKey = new Object();
        Object cacheKey = WeakCache.CacheKey.valueOf(key, refQueue);

        // lazily install the 2nd level valuesMap for the particular cacheKey
        // 从缓存map中读取指定cacheKey的缓存数据valuesMap
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            //如果valuesMap为null,则新增
            // putIfAbsent方法解释:如果值存在则返回值,并且不对原来的值做任何更改,如果不存在则新增,并返回null
            //map.putIfAbsent 是map中新增的一个方法 存在则返回,不存在put然后在返回
            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
        //获取subKey,这里用到了上面提到的Proxy的静态内部类 KeyFactory:subKeyFactory.apply(ket,parameter)
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        // 从valuesMap中获取supplier
        Supplier<V> supplier = valuesMap.get(subKey);
        WeakCache.Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier might be a Factory or a Cacheva lue<V> instance
                //  4、从工厂中获取代理类对象
                V value = supplier.get();
                if (value != null) {
                    //5、返回
                    return value;
                }
            }
            // else no supplier in cache
            // or a supplier that returned null (could be a cleared Cacheva lue
            // or a Factory that wasn't successful in installing the Cacheva lue)

            // lazily construct a Factory
            //1、实例化工厂
            if (factory == null) {
                factory = new WeakCache.Factory(key, parameter, subKey, valuesMap);
            }

            if (supplier == null) {
                //2、将supplier保存到valuesMap中
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    // successfully installed Factory
                    // 3、赋值
                    supplier = factory;
                }
                // else retry with winning supplier
            } else {
                //如果subKey和supplier都匹配则则将supplier替换为新生成的factory
                if (valuesMap.replace(subKey, supplier, factory)) {
                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    //替换成功赋值
                    supplier = factory;
                } else {
                    // retry with current supplier
                    //使用当前的supplier进行重试
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }

  因为程序中Proxy.newProxyInstance是第一次执行,所以while循环开始的时候,supplier,valuesMap都是null。在这个前提下,我为代码的执行顺序做了一个编号,从1-5执行。

 可以看到第5步,也就是源代码的第47行将结果返回,那么,代理类对象就是在第4步,也就是第43行生成的。而且也可以从第3步,也就是第65行发现supplier就是factory。

那么接下来,就分析一下Factory.get方法。

6、Factory.get方法

Factory类是WeakCache的内部类。这个类中除去构造方法外,就是get方法了,下面是这个代码的实现:

    /**
     * Factory 实现类Supplier 接口
     */
    private fin
首页 上一页 1 2 3 4 5 6 下一页 尾页 3/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇集合 P1 集合 下一篇Java开发工具IntelliJ IDEA 2020...

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目