Retrofit源码解密之----------动态代理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010221508/article/details/88354447

写在前面的话

Retrofit是开源的网络请求框架,是目前最火的框架之一,也是求职面试之中被提问的比较多的知识点。最近抽了点时间阅读了一下Retrofit源代码,给大家分享一下

  public <T> T create(final Class<T> service) {
  	//判断service是不是个接口
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    //通过动态代理为请求接口创建一个对象
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();
          /*
		  *请求接口里的每个方法调用的时候,都会触发这个方法回调
		  *@param method 代表的请求方法
		  *@param args 请求方法传入的参数
		  */
          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //对请求方法进项解析,找出其请求头,请求地址(除去baseUrl),请求方法
            //所需要的参数,然后保存到ServiceMethod的对象里面去
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
             //将解析请求方法得到的数据和需要的参数传入OKHttpCall中,执行网络请求 
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

这段代码是Retrofit为请求接口创建代理对象用的,使用到了动态代理技术,动态代理技术是动态为接口创建代理对象的技术
下面看看接口的动态对象是怎么创建的,进入到Proxy#newProxyInstance方法里面看一下

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException
{
    Objects.requireNonNull(h);

    final Class<?>[] intfs = interfaces.clone();
    /*
     * Look up or generate the designated proxy class.
     */
    Class<?> cl = getProxyClass0(loader, intfs);

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        if (!Modifier.isPublic(cl.getModifiers())) {
            // Android-changed: Removed AccessController.doPrivileged
            cons.setAccessible(true);
        }
        return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
       
    } catch (InvocationTargetException e) {
        
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString(), e);
    }
}

看到这个方法里面调用了

		Class<?> cl = getProxyClass0(loader, intfs);
		final Constructor<?> cons = cl.getConstructor(constructorParams);
		return cons.newInstance(new Object[]{h});

这三个方法,第一个方法是获取为接口创建的代理类Class对象 ,第二三个方法是通过反射方式为这个代理类创建对象并且返回,那么我们看看这个代理类是怎么获取到的。
进入到Proxy#getProxyClass0方法看看代理类是怎么得到的

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
    return proxyClassCache.get(loader, interfaces);
}

看到它通过proxyClassCache.get(loader, interfaces)获取代理类的
那么我们看看这个proxyClassCache是何许东西??????

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

可以看到,它属于Proxy的一个静态成员常量(final修饰了),是一个容器,key是KeyFactory对象,value是ProxyClassFactory对象,看一下ProxyClassFactory这个类,它重写了其父类BiFunction的一个apply方法

@Override
    public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
    		...
            return generateProxy(proxyName, interfaces, loader, methodsArray,
                                 exceptionsArray);
        }
    }

可以看到它调用了

generateProxy(proxyName, interfaces, loader, methodsArray,
                                 exceptionsArray)

这个方法,进入这个方法

@FastNative
private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
                                             ClassLoader loader, Method[] methods,
                                             Class<?>[][] exceptions);

可以看到它是一个native方法,而接口的代理类就是通过这个native方法创建的。

在返回到

proxyClassCache.get(loader, interfaces)

这个方法,进入这个方法,看看执行了什么 (WeakCache#get)

public V get(K key, P parameter) {
    ...
    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
    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
            V value = supplier.get();
            if (value != null) {
                return value;
            }
        }
    }
    ...
}

可以看到这几句关键代码

ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
Supplier<V> supplier = valuesMap.get(subKey);
...
V value = supplier.get();
        if (value != null) {
            return value;
        }

可以看到选获取到了一个ConcurrentMap对象valuesMap,又通过valueMap获取到了一个Supplier对象supplier,紧接着调用它的get方法,获得了一个value,并且返回了它,那么这个value就是我们需要的接口的代理类了,那么看看这个get方法执行了什么操作,进入到

supplier.get();

这个方法中

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

可以看到Supplier只是一个接口,我们看一下他的实现类

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
        // re-check
        Supplier<V> supplier = valuesMap.get(subKey);
        if (supplier != this) {
            // something changed while we were waiting:
            // might be that we were replaced by a CacheValue
            // or were removed because of failure ->
            // return null to signal WeakCache.get() to retry
            // the loop
            return null;
        }
        // else still us (supplier == this)

        // create new 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)
        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;
    }
}

最终supplier.get()方法调用到了Factory的get方法,在Factory方法里调用了这一句代码

 value = Objects.requireNonNull(valueFactory.apply(key, parameter));

可以看到最终调用到了 valueFactory.apply(key, parameter);这个方法

我们前面分析过,接口的代理类的创建就是在这个对象的这个方法里面做的,即最终会调用到ProxyClassFactory的apply方法里面去创建代理类。
至此代理对象的创建已经分析完了。

猜你喜欢

转载自blog.csdn.net/u010221508/article/details/88354447