接着上回,分析过使用Retrofit的流程后,本篇继续分析 Retrofit # create
方法(文章末尾附有时序图)
一、Retrofit # Create
create方法中,主要的是 loadServiceMethod
方法分析,其余都在注释中进行的标注(省略部分不重要代码)
// Retrofit.java
public T create(final Class service) {
//判断是否为 interface
validateServiceInterface(service);
//1, java 动态代理,创建 interface 实例
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class>[] { service },
new InvocationHandler() {
//2,平台,一般为 Android
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 {
// .... 省略....
//主要分析该方法
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
1.1、 Retrofit # loadServiceMethod
该方法创建 ServiceMethod
实际new的时候,调用的是 ServiceMethod.parseAnnotations
继续分析该方法
// Retrofit.java
ServiceMethod> loadServiceMethod(Method method) {
//1,尝试从缓存中获取
ServiceMethod> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//2,解析注解, this = Retrofit ; method:指的是当前调用的方法
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);//进行缓存
}
}
return result;
}
二、 ServiceMethod # parseAnnotations
该方法主要是对 注解 进行解析,需要注意的有以下几个地方
- 该
ServiceMethod
为抽象类,包含了上面所调用的create
方法中调用的invoke
抽象方法。 -
RequestFactory.parseAnnotations(retrofit,method);
该方法,对 method 和参数 注解 进行解析。 -
HttpServiceMethod
是ServiceMethod
子类,下面会对HttpServiceMethod.parseAnnotations
进行分析。
//ServiceMethod.java
abstract class ServiceMethod {
//关键方法
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method){
//1,通过‘RequestFactory’工厂, 解析‘方法注解’
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.");
}
//ServiceMethod 的子类
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
//抽象方法,在 create 中调用
abstract @Nullable T invoke(Object[] args);
}
三、RequestFactory.parseAnnotations
接着上面,对 RequestFactory.parseAnnotations
分析。RequestFactory
转译过来是 ‘请求工厂’ , parseAnnotations
方法通过 Builder.build 创建了一个RequestFactory
,只需要看一下 new Builder()、build() 中做了什么操作。
//RequestFactory.java
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
-
new Builder(retrofit, method)
将传入的参数retrofit、method
进行了解析(具体见注释)
//RequestFactory.java
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//1,拿到方法注解。例如:@GET、@POST.....
this.methodAnnotations = method.getAnnotations();
//2.获取 方法的‘参数’ 类型。例如:int、String....。
this.parameterTypes = method.getGenericParameterTypes();
//3.获取 方法参数的‘注解’。 例如: @Query 、@Filed....
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
- 继续看
build();
方法,该方法主要是对 方法、参数 进行解析
//RequestFactory.java
RequestFactory build() {
//1,解析 ‘方法注解’
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//.......... 省略一些判断.....
//2.解析 ‘参数’
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);
}
-
build();
-->parseMethodAnnotation
,该方法见到了我们熟悉的注解,也就是我们在定义接口方法时候,写到方法上的例如:@GET、@POST
等等注解 进行解析。
//RequestFactory.java
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
-
build();
-->parseParameter
解析参数。parseParameter
- >parseParameterAnnotation
中对具体的参数注解进行了解析
//RequestFactory.java
private @Nullable ParameterHandler> parseParameter(int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
ParameterHandler> result = null;
if (annotations != null) {
//重点是这个 for循环
for (Annotation annotation : annotations) {
ParameterHandler> annotationAction =
parseParameterAnnotation(p, parameterType, annotations, annotation);
//..... 省略一些判断.....
result = annotationAction;
}
}
//..... 省略一些判断.....
return result;
}
-
parseParameter
- >parseParameterAnnotation
。重点解析 ‘参数注解’的方法,由于篇幅原因,简单分析两个注解。
可以看到在下面代码中,看到了我们经常使用的注解@Url、@Query、@Path
在参数中添加的注解,主要是在这个方法中进行解析。
//RequestFactory.java
@Nullable
private ParameterHandler> parseParameterAnnotation(int p, Type type, Annotation[] annotations, Annotation annotation) {
if (annotation instanceof Url) {
//........省略了些判断..........
gotUrl = true;
if (type == HttpUrl.class
|| type == String.class
|| type == URI.class
|| (type instanceof Class && "android.net.Uri".equals(((Class>) type).getName()))) {
return new ParameterHandler.RelativeUrl(method, p);
} else {
throw parameterError(method, p,
"@Url must be okhttp3.HttpUrl, String, java.net.URI, or android.net.Uri type.");
}
} else if (annotation instanceof Path) {
//........省略了些判断..........
gotPath = true;
Path path = (Path) annotation;
String name = path.value();
validatePathName(p, name);
Converter, String> converter = retrofit.stringConverter(type, annotations);
return new ParameterHandler.Path<>(method, p, name, converter, path.encoded());
} else if (annotation instanceof Query) {
validateResolvableType(p, type);
Query query = (Query) annotation;
String name = query.value();
boolean encoded = query.encoded();
Class> rawParameterType = Utils.getRawType(type);
gotQuery = true;
if (Iterable.class.isAssignableFrom(rawParameterType)) {
if (!(type instanceof ParameterizedType)) {
throw parameterError(method, p, rawParameterType.getSimpleName()
+ " must include generic type (e.g., "
+ rawParameterType.getSimpleName()
+ ")");
}
ParameterizedType parameterizedType = (ParameterizedType) type;
Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
Converter, String> converter =
retrofit.stringConverter(iterableType, annotations);
return new ParameterHandler.Query<>(name, converter, encoded).iterable();
}
//.... 省略了一些参数注解...
}
ParameterHandler 包含了对应各个参数注解的内部类,如下图
到这里,RequestFactory # build()
方法以及分析完毕,该类主要是对请求的方法以及参数及其注解进行解析。
2.1、回到 ServiceMethod#parseAnnotations
继续往下看 return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
上面经过 RequestFactory
对请求的 方法以及参数 进行了解析,会继续执行到 HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
//HttpServiceMethod.java
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//.....省略对 kt 支持判断.....
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
//.....省略对 kt 支持判断.....
} else {
//方法的返回类型,例如:String、int、Resoponse 等
adapterType = method.getGenericReturnType();
}
//请求适配器
CallAdapter callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response)");
}
// TODO support Unit for Kotlin?
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter>) callAdapter,
continuationBodyNullable);
}
}
注:忽略对Kt 的分析
该方法中,需要注意的是 createCallAdapter 方法,往下看
//HttpServiceMethod.java
CallAdapter callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);
//HttpServiceMethod.java
private static CallAdapter createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
//Retrofit.java
//注意该,?> 代表的是 Response, Return 类型
public CallAdapter, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
2.2 在分析nextCallAdapter
之前,先解释一下 callAdapterFactories
请求适配器工厂
//Retrofit.java
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
例如:一般我们项目适配了RxJava的时候,会调用下面方法,来进行 Call
的转换,将Call
转换成 Observable
addCallAdapterFactory(RxJava2CallAdapterFactory.create())
在Retrofit -> build()
方法中,添加了默认的CallAdapter
,也就是 DefaultCallAdapterFactory
默认返回的是 Call
//Retrofit.java
public Retrofit build() {
//........
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 添加默认调用适配器。
List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
//..............
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
默认的CallAdapter
//Platform.java
List extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
//默认支持 java 8,有2个默认Factory
return hasJava8Types
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
2.3继续跟到 Retrofit # nextCallAdapter
//Retrofit.java
public CallAdapter, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
//....
//skipPast = null, 那么 start = 1
//由于SDK>24 支持 java8,则默认的callAdapterFactories.size(); = 2
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
// 注意这里的 get,在没有别的CallAdapter 实际是调用的DefaultCallAdapterFactory # get
CallAdapter, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
//省略....
}
注意 nextCallAdapter
中 for循环,调用get方法,当用户没有手动添加 CallAdapter
的时候,调用的是DefaultCallAdapterFactory#get()
返回的是 ExecutorCallbackCall
。
分析完请求适配器createCallAdapter
,继续看2.1、 ServiceMethod#parseAnnotations
//HttpServiceMethod.java
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//....省略
//拿到 Call 适配器
CallAdapter callAdapter =createCallAdapter(retrofit, method, adapterType, annotations);
// 返回值类型
Type responseType = callAdapter.responseType();
//... 省略一些判断
//返回值,转换
Converter responseConverter = createResponseConverter(retrofit, method, responseType);
//省略.. 下面会继续分析
2.4 数据转换器 createResponseConverter
,其实这里和上面分析CallAdapter
流程差不多,具体如下:
//HttpServiceMethod.java
private static Converter createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}
//Retrofit.java
public Converter responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
//Retrofit.java
public Converter nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
//....
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter) converter;
}
}
//.......省略
}
converterFactories 转换工厂,将返回值,进行转换例如:
//使用:
.addConverterFactory(FastJsonConverterFactory.create())//数据 fastJson 转换器
//Retrofit.java
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
也在Retrofit ->build()
中有默认值为:
//Retrofit.java
public Retrofit build() {
//...省略
// Make a defensive copy of the converters.
List converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());//内部转换器
converterFactories.addAll(this.converterFactories); //用户添加的数据转换器
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
//PlatForm.java
List extends Converter.Factory> defaultConverterFactories() {
return hasJava8Types
? singletonList(OptionalConverterFactory.INSTANCE)
: emptyList();
}
分析完CallAdapter、Converter
, 继续看2.1 HttpServiceMethod # parseAnnotations
//HttpServiceMethod.java
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//......
CallAdapter callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
//忽略 kt分析
}
该方法在不支持kt情况下,返回CallAdapted
,CallAdapted
继承自HttpServiceMethod
//HttpServiceMethod.java
static final class CallAdapted extends HttpServiceMethod {
private final CallAdapter callAdapter;
CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter responseConverter,
CallAdapter callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override protected ReturnT adapt(Call call, Object[] args) {
//注意,这里的 callAdapter 是,DefaultCallAdapterFactory
return callAdapter.adapt(call);
}
}
HttpServiceMethod
继承自 ServiceMethod
abstract class HttpServiceMethod extends ServiceMethod{
...
@Override final @Nullable ReturnT invoke(Object[] args) {
Call call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
}
注意:在Retrofit->create()
调用的是 ServiceMethod # invoke
方法,最终调到了 HttpServiceMethod # invoke
, invoke
-> adapt()
//Retrofit.java
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
到这里Retrofit # create() 方法分析完毕。时序图如下: