栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDK动态代理源码解读

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDK动态代理源码解读

入口是java.lang.reflect.Proxy#newProxyInstance

简化一下就三步:

//从缓存查找代理类,或者生成指定的代理类
Class cl = getProxyClass0(loader, intfs);
//获取public构造器,如果不是public 设置为可访问
final Constructor cons = cl.getConstructor(constructorParams)
//调用有参构造器创建实例
cons.newInstance(new Object[]{h})

再来看看java.lang.reflect.Proxy#getProxyClass0()这个方法,注释的意思是,如果当前classLoader已经创建了代理类,就copy一份,如果没有就创建一个。里面实际是调用了

proxyClassCache.get(loader, interfaces)

我们再来看WeakCache.get(loader, interfaces)这个方法。

      //1.包装key为CacheKey    
      Object cacheKey = CacheKey.valueOf(key, refQueue);      
      // lazily install the 2nd level valuesMap for the particular cacheKey
        ConcurrentMap> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            ConcurrentMap> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }

        // create subKey and retrieve the possible Supplier stored by that
        // subKey from valuesMap
        //2.通过SubKeyFactory创建key对象
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier might be a Factory or a Cachevalue instance
                //4.实际调用了内部类Factory的get()方法,创建了一个代理类
                V value = supplier.get();
                if (value != null) {
                    return value;
                }
            }
            //.........省略了一部分
            // lazily construct a Factory
            //3.实例化内部类Factory
            if (factory == null) {
                factory = new Factory(key, parameter, subKey, valuesMap);
            }
            //..........省略...........
        }

这个内部类java.lang.reflect.WeakCache.Factory#get的源码如下

            // create new value
            //1.关键代码:创建Value即代理类
            V value = null;
            try {
                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)
            // 2.包装value成Cachevalue
            Cachevalue cachevalue = new Cachevalue<>(value);

            //3. 放到reverseMap,以及替换掉旧的valuesMap中的value
            reverseMap.put(cachevalue, Boolean.TRUE);

 第二步valueFactory.apply(key, parameter)很重要。

在Proxy中有个方法分别创建了KeyFactory(这个就是keyFactory对象)和ProxyClassFactory(这个就是valueFactory对象)

    private static final WeakCache[], Class>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

 那我们就来看Proxy的内部类ProxyClassFactory.apply(key, parameter)这个方法。

            //上面代码略过,是选择包名,以接口包作为包名            
            
            //1.给代理类命名。包名+类名+自增数
            long num = nextUniqueNumber.getAndIncrement();
            String proxyName = proxyPkg + proxyClassNamePrefix + num;

            
            //2.生成特定的代理类字节码
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                //3.将字节码转换为对象
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
            }

 这三部走完就算是完成创建代理类的细节了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/785982.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号