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<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            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
        //2.通过SubKeyFactory创建key对象
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier might be a Factory or a CacheValue<V> 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<V> cacheValue = new CacheValue<>(value);

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

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

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

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞翔的咩咩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值