android之Retrofit2原理解析
作者:互联网
1.前言
Retrofit2框架是对请求的封装,请求框架使用OKhttp框架,本篇不分析OKhttp框架,只分析Retrofit2框架如何将Java接口通过动态代理生成一个个的请求对象。
2.Retrofit2使用
//retrofit2包引用
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
/**
* Retrofit工具测试类
*
* @author zhukui
*/
public abstract class RetrofitUtil {
/**
* 用户相关请求
*/
public interface IUserRequest {
@GET("userInfo/{userId}/")
Call<List<String>> getUserInfo(@Path("userId") String userId);
}
/**
* 测试方法
*/
private void test() {
//Retrofit对象创建,这里用的是建造者模式创建
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
//动态代理生成请求对象,并用接口多态
IUserRequest service = retrofit.create(IUserRequest.class);
//请求对象
Call<List<String>> request = service.getUserInfo("10086");
//同步请求
try {
Response<List<String>> response = request.execute();
List<String> list = response.body();
} catch (Exception e) {
e.printStackTrace();
}
//异步请求
request.enqueue(new Callback<List<String>>() {
@Override
public void onResponse(Call<List<String>> call, Response<List<String>> response) {
List<String> list = response.body();
}
@Override
public void onFailure(Call<List<String>> call, Throwable t) {
t.printStackTrace();
}
});
}
}
3.Retrofit2源码分析
1.Retrofit对象创建
主要基于建造者模式创建,baseUrl()为主要方法。IUserRequest为用户类请求接口,getUserInfo为模拟获取用户信息接口,接口注解及接口参数配置可查看Retrofit官网说明,不是本篇侧重点,这里继续往下。
2.retrofit.create方法 - 重点
public <T> T create(final Class<T> 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();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable 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);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
Utils.validateServiceInterface(service)判断是否是interface接口,如果这里是普通Java类型会直接抛出异常。 if (validateEagerly) { eagerlyValidateMethods(service);} 这里可以设置是否缓存接口解析,非重点直接下一步 Proxy.newProxyInstance这是调用java的动态代理生成了代理类。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
loader: 用哪个类加载器去加载代理对象
interfaces:动态代理类需要实现的接口
h:动态代理方法在执行时,会调用h里面的invoke方法去执行
Proxy.newProxyInstance程序运行时产生一个类$proxy0
$proxy0类继承自Proxy类,实现了目标对象的父类接口(借鉴的百度提供的源码)
$proxy0类有多个Method成员变量,它的静态代码块给Method赋值为我们自己的接口的实现类的对应的Method对象
$proxy0实现接口的方法调用了super.h.invoke(参数),这里的参数包括Method变量
//$proxy0的源码
public final class $Proxy0 extends Proxy implements Subject {
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode",
new Class[0]);
m3 = Class.forName("接口的实现类的路径").getMethod("实现类的方法",
new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString",
new Class[0]);
} catch (NoSuchMethodException nosuchmethodexception) {
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
} //static
public $Proxy0(InvocationHandler invocationhandler) {
super(invocationhandler);
}
@Override
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final void 接口的实现类的方法() {
try {
super.h.invoke(this, m3, null);
return;
} catch (Error e) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final String toString() {
try {
return (String) super.h.invoke(this, m2, null);
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
}
代理对象调接口中的方法---代理对象的真身是$proxy0 调用了对应的方法---此方法内部调用其父类的成员h调用h的invoke方法---就是调用传入了InvocationHandler的invoke方法,至于返回值,那就看我们的InvocationHandler的invoke方法怎么写。这里Retrofit2重写了invoke方法返回值,实际为每个返回值为Call的方法返回了OkHttpCall对象。
3.loadServiceMethod分析
loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
private final Map<Method, ServiceMethod<?>>
serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
我们继续看ServiceMethod.parseAnnotations方法。
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
ServiceMethod.parseAnnotations方法中RequestFactory.parseAnnotations()中进行方法注解、方法参数、方法参数注解等处理,并且负责创建请求时拼接resultful格式。
@GET("userInfo/{userId}/")
Call<List<String>> getUserInfo(@Path("userId") String userId);
这里userId传的是"10086",会将userId值赋值到login/{userId}/中,即拼接为/userInfo/10086,
根据 baseUrl配置,最终 请求地址+请求参数 结果 :
baseUrl = https://api.github.com
relativeUrl = /userInfo/10086
最终请求为:https://api.github.com/userInfo/10086
private final HttpUrl baseUrl;
private @Nullable String relativeUrl;
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
//这里处理方法,方法上的注解,参数类型,参数注解
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
//解析方法注解
parseMethodAnnotation(annotation);
}
//......
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++)
{
parameterHandlers[p] =
//解析参数
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p ==
lastParameter);
}
//......
return new RequestFactory(this);
}
//解析参数
ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
//.....
//解析参数注解
parseParameterAnnotation(p, parameterType, annotations, annotation);
Path path = (Path) annotation;
String name = path.value();
validatePathName(p, name);
//.....
}
//解析参数注解
@Nullable
private ParameterHandler<?> parseParameterAnnotation(
int p, Type type, Annotation[] annotations, Annotation annotation) {
//.....
//处理参数注解Path
Path path = (Path) annotation;
String name = path.value();
validatePathName(p, name);
//.....
}
//创建请求
okhttp3.Request create(Object[] args) throws IOException {
//.....
}
继续看return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//...
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
}
static final class SuspendForBody<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
private final boolean isNullable;
//...
}
可以看到 HttpServiceMethod是ServiceMethod子类,最终返回的SuspendForBody也是ServiceMethod子类,到这里就可以看到上面invoke方法的最终实现。
4.invoke方法
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
我们可以看到此处new OkHttpCall()对象,并且传了requestFactory等必要的请求参数,这里就将每一个方法翻译成了一个个请求。
标签:args,return,invoke,Object,Retrofit2,new,android,解析,method 来源: https://blog.csdn.net/zhukui66/article/details/121849311