写在前面的话
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方法里面去创建代理类。
至此代理对象的创建已经分析完了。