与 OkHttp 的区别
封装不同: Retrofit 实际上是基于 OkHttp
实现的并封装了具体的请求,线程切换以及数据转换。 Retrofit 通过使用代理,外观,策略模式对 OkHttp 进行了封装。 OkHttp 是基于 Http 协议封装的一套请求客户端
职责不同: Retrofit 主要负责应用层面的封装,面向开发者,方便使用,比如请求参数,响应数据的处理,错误处理等等。 OkHttp 主要负责 socket 部分的优化与封装,比如网络访问,多路复用,buffer 缓存,数据压缩等等。
Retrofit 的创建过程
Retrofit 是通过建造者模式构建出来的,查看其 Builder 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public Builder () { this (Platform.get()); } private static Platform findPlatform () { try { Class.forName("android.os.Build" ); if (Build.VERSION.SDK_INT != 0 ) { return new Android (); } } catch (ClassNotFoundException ignored) { } return new Platform (true ); }
查看其 build 方法,会做一些默认的初始化工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public Retrofit build () { if (baseUrl == null ) { throw new IllegalStateException ("Base URL required." ); } okhttp3.Call.Factory callFactory = this .callFactory; if (callFactory == null ) { callFactory = new OkHttpClient (); } Executor callbackExecutor = this .callbackExecutor; if (callbackExecutor == null ) { callbackExecutor = platform.defaultCallbackExecutor(); } List<CallAdapter.Factory> callAdapterFactories = new ArrayList <>(this .callAdapterFactories); callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); List<Converter.Factory> converterFactories = new ArrayList <>( 1 + this .converterFactories.size() + platform.defaultConverterFactoriesSize()); converterFactories.add(new BuiltInConverters ()); converterFactories.addAll(this .converterFactories); converterFactories.addAll(platform.defaultConverterFactories()); return new Retrofit (callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); } }
Call 的创建过程
1 2 INetApiService iNetApiService = retrofit.create(INetApiService.class);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public <T> T create (final Class<T> service) { validateServiceInterface(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 (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); } }); }
说明 Retrofit
不是在创建 Service
接口对应对象时就立即对所有该接口中的所有方法都进行注解的解析,而是采用了在方法被调用时才进行注解的解析这种懒加载的思想。接下来查看其 loadServiceMethod():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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) ; }
1 2 3 4 5 6 static RequestFactory parseAnnotations (Retrofit retrofit, Method method) { return new Builder (retrofit, method).build(); }
1 2 3 4 5 6 7 8 Builder(Retrofit retrofit, Method method) { this .retrofit = retrofit; this .method = method; this .methodAnnotations = method.getAnnotations(); this .parameterTypes = method.getGenericParameterTypes(); this .parameterAnnotationsArray = method.getParameterAnnotations(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 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); } if (relativeUrl == null && !gotUrl) { throw methodError(method, "Missing either @%s URL or @Url parameter." , httpMethod); } if (!isFormEncoded && !isMultipart && !hasBody && gotBody) { throw methodError(method, "Non-body HTTP method cannot contain @Body." ); } if (isFormEncoded && !gotField) { throw methodError(method, "Form-encoded method must contain at least one @Field." ); } if (isMultipart && !gotPart) { throw methodError(method, "Multipart method must contain at least one @Part." ); } return new RequestFactory (this ); }
查看 parseMethodAnnotation() ,实际上就是对每一种 HTTP 所支持的类型进行了支持,获取到了对应注解中的 url,并调用parseHttpMethodAndPath
对不同 HTTP 请求方式和 Path 进行了赋值,同时通过正则表达式保证了这个接口的 Path 中没有包含参数。同时对 Headers 注解则是通过 parseHeaders
将传递进来的 Headers
列表解析为了对应的 Headers
对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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 ; } }
接着查看 HttpServiceMethod.parseAnnotations():
新版的 Retrofit 对 Kotlin 的协程进行了支持。HttpServiceMethod.parseAnnotations
的主要作用就是创建 CallAdapter
以及 Converter 对象,并构建对应 HttpServiceMethod
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations ( Retrofit retrofit, Method method, RequestFactory requestFactory) { boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction; boolean continuationWantsResponse = false ; boolean continuationBodyNullable = false ; Annotation[] annotations = method.getAnnotations(); Type adapterType; if (isKotlinSuspendFunction) { Type[] parameterTypes = method.getGenericParameterTypes(); Type responseType = Utils.getParameterLowerBound(0 , (ParameterizedType) parameterTypes[parameterTypes.length - 1 ]); if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) { responseType = Utils.getParameterUpperBound(0 , (ParameterizedType) responseType); continuationWantsResponse = true ; } else { } adapterType = new Utils .ParameterizedTypeImpl(null , Call.class, responseType); annotations = SkipCallbackExecutorImpl.ensurePresent(annotations); } else { adapterType = method.getGenericReturnType(); } CallAdapter<ResponseT, ReturnT> 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<String>)" ); } if (requestFactory.httpMethod.equals("HEAD" ) && !Void.class.equals(responseType)) { throw methodError(method, "HEAD method must use Void as response type." ); } Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType); okhttp3.Call.Factory callFactory = retrofit.callFactory; if (!isKotlinSuspendFunction) { return new CallAdapted <>(requestFactory, callFactory, responseConverter, callAdapter); } else if (continuationWantsResponse) { return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse <>(requestFactory, callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter); } else { return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody <>(requestFactory, callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter, continuationBodyNullable); } }
CallAdapter 是用于将Call
对象适配为需要的类型 T 对象的。它的声明如下:
1 2 3 4 5 6 public interface CallAdapter <R, T> { Type responseType () ; T adapt (Call<R> call) ; }
它是通过 createCallAdapter() 创建的,createCallAdapter() 内部调用了 retrofit.callAdapter(),之后调用了 retrofit.nextCallAdapter():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { Objects.requireNonNull(returnType, "returnType == null" ); Objects.requireNonNull(annotations, "annotations == null" ); int start = callAdapterFactories.indexOf(skipPast) + 1 ; for (int i = start, count = callAdapterFactories.size(); i < count; i++) { CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this ); if (adapter != null ) { return adapter; } } }
在创建 Retrofit 对象时,build() 中有一个默认的 CallAdapter
工厂 DefaultCallAdapterFactory
,它的优先级比所有自定义工厂要低 ,它在创建时会传入一个 Executor
,看它的 get 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @Override public @Nullable CallAdapter<?, ?> get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Call.class) { return null ; } if (!(returnType instanceof ParameterizedType)) { throw new IllegalArgumentException ( "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>" ); } final Type responseType = Utils.getParameterUpperBound(0 , (ParameterizedType) returnType); final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : callbackExecutor; return new CallAdapter <Object, Call<?>>() { @Override public Type responseType () { return responseType; } @Override public Call<Object> adapt (Call<Object> call) { return executor = = null ? call : new ExecutorCallbackCall <>(executor, call); } }; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 static final class ExecutorCallbackCall <T> implements Call <T> { final Executor callbackExecutor; final Call<T> delegate; ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) { this .callbackExecutor = callbackExecutor; this .delegate = delegate; } @Override public void enqueue (final Callback<T> callback) { Objects.requireNonNull(callback, "callback == null" ); delegate.enqueue(new Callback <T>() { @Override public void onResponse (Call<T> call, final Response<T> response) { callbackExecutor.execute(() -> { if (delegate.isCanceled()) { callback.onFailure(ExecutorCallbackCall.this , new IOException ("Canceled" )); } else { callback.onResponse(ExecutorCallbackCall.this , response); } }); } @Override public void onFailure (Call<T> call, final Throwable t) { callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this , t)); } }); } }
Converter
类,用于将类型 F 的数据转换为类型 T:
1 2 3 4 public interface Converter <F, T> { @Nullable T convert (F value) throws IOException; }
它是通过 createResponseConverter() (class:HttpServiceMethod)来创建,后续调用到了 nextResponseBodyConverter():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public <T> Converter<ResponseBody, T> nextResponseBodyConverter ( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { Objects.requireNonNull(type, "type == null" ); Objects.requireNonNull(annotations, "annotations == null" ); int start = converterFactories.indexOf(skipPast) + 1 ; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this ); if (converter != null ) { return (Converter<ResponseBody, T>) converter; } } }
Retrofit 中内置了两个 Converter.Factory:
BuiltInConverters:优先级比所有自定义工厂要高,以避免其他工厂覆盖它的方法。其中实现了多个转换器如将 ResponseBody
转换为 Void 或 Unit,将 Object 转换为 String 等。
OptionalConverterFactory:优先级比所有自定义工厂的优先级更低。通过 platform 获取到的 defaultConverterFactories
,它是为了支持 Java 8 的 Optional 而实现的,Optional 是 Java 8 引入的用来解决空指针异常的类。
ServiceMethod 类是一个抽象类,需要子类 HttpServiceMethod 对 invoke 方法进行实现。
1 2 3 4 5 6 7 8 9 10 11 @Override final @Nullable ReturnT invoke (Object[] args) { Call<ResponseT> call = new OkHttpCall <>(requestFactory, args, callFactory, responseConverter); return adapt(call, args); } protected abstract @Nullable ReturnT adapt (Call<ResponseT> call, Object[] args) ;
HttpServiceMethod 共有三个子类:
并非使用协程的情况下的 CallAdapted
类:通过传递进来的 CallAdapter
对 Call 进行了转换。
使用协程的情况下为了配合协程的 SuspendForResponse
类:首先根据传递进来的 Call 构造了一个参数为 Response
的 Continuation
对象然后通过 Kotlin 实现的 awaitResponse
方法将 call 的 enqueue
异步回调过程封装为了一个 suspend 的函数。
使用协程的情况下为了配合协程的 SuspendForBody
类:根据传递进来的 Call 构造了一个 Continuation
对象然后通过 Kotlin 实现的 await 或 awaitNullable
方法将 call 的 enqueue
异步回调过程封装为了一个 suspend 的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public interface Call <T> extends Cloneable { Response<T> execute () throws IOException; void enqueue (Callback<T> callback) ; boolean isExecuted () ; void cancel () ; boolean isCanceled () ; Call<T> clone () ; Request request () ; }
如果没有传入 CalAdapter 的话,默认情况下返回的 Call 实际上是 OkHttpCall 对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 @Override public void enqueue (final Callback<T> callback) { Objects.requireNonNull(callback, "callback == null" ); okhttp3.Call call; Throwable failure; synchronized (this ) { if (executed) throw new IllegalStateException ("Already executed." ); executed = true ; call = rawCall; failure = creationFailure; if (call == null && failure == null ) { try { call = rawCall = createRawCall(); } catch (Throwable t) { throwIfFatal(t); failure = creationFailure = t; } } } if (failure != null ) { callback.onFailure(this , failure); return ; } if (canceled) { call.cancel(); } call.enqueue(new okhttp3 .Callback() { @Override public void onResponse (okhttp3.Call call, okhttp3.Response rawResponse) { Response<T> response; try { response = parseResponse(rawResponse); } catch (Throwable e) { throwIfFatal(e); callFailure(e); return ; } try { callback.onResponse(OkHttpCall.this , response); } catch (Throwable t) { throwIfFatal(t); t.printStackTrace(); } } @Override public void onFailure (okhttp3.Call call, IOException e) { callFailure(e); } private void callFailure (Throwable e) { try { callback.onFailure(OkHttpCall.this , e); } catch (Throwable t) { throwIfFatal(t); t.printStackTrace(); } } }); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 @Override public Response<T> execute () throws IOException { okhttp3.Call call; synchronized (this ) { if (executed) throw new IllegalStateException ("Already executed." ); executed = true ; if (creationFailure != null ) { if (creationFailure instanceof IOException) { throw (IOException) creationFailure; } else if (creationFailure instanceof RuntimeException) { throw (RuntimeException) creationFailure; } else { throw (Error) creationFailure; } } call = rawCall; if (call == null ) { try { call = rawCall = createRawCall(); } catch (IOException | RuntimeException | Error e) { throwIfFatal(e); creationFailure = e; throw e; } } } if (canceled) { call.cancel(); } return parseResponse(call.execute()); }
okhttp3.Call 的创建:
1 2 3 4 5 6 7 private okhttp3.Call createRawCall () throws IOException { okhttp3.Call call = callFactory.newCall(requestFactory.create(args)); if (call == null ) { throw new NullPointerException ("Call.Factory returned null." ); } return call; }
它实际上是调用了 callFactory
的 newCall
方法进行创建,而传入的 okhttp3.Request
则是通过 requestFactory.create
创建的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 okhttp3.Request create (Object[] args) throws IOException { @SuppressWarnings("unchecked") ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers; int argumentCount = args.length; if (argumentCount != handlers.length) { throw new IllegalArgumentException ("Argument count (" + argumentCount + ") doesn't match expected count (" + handlers.length + ")" ); } RequestBuilder requestBuilder = new RequestBuilder (httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody, isFormEncoded, isMultipart); if (isKotlinSuspendFunction) { argumentCount--; } List<Object> argumentList = new ArrayList <>(argumentCount); for (int p = 0 ; p < argumentCount; p++) { argumentList.add(args[p]); handlers[p].apply(requestBuilder, args[p]); } return requestBuilder.get() .tag(Invocation.class, new Invocation (method, argumentList)) .build(); }
接着看 parseResponse
是如何对 Response 进行解析的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Response<T> parseResponse (okhttp3.Response rawResponse) throws IOException { ResponseBody rawBody = rawResponse.body(); rawResponse = rawResponse.newBuilder() .body(new NoContentResponseBody (rawBody.contentType(), rawBody.contentLength())) .build(); ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody (rawBody); try { T body = responseConverter.convert(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { catchingBody.throwIfCaught(); throw e; } }
总结
Retrofit
的注解是一种运行时注解,它通过动态代理对 Service 对象进行创建,通过反射对注解进行解析 ,这样虽然会有一定性能的损耗,但性能的损耗却带来了十分易用的 API。用户所写的 Service 接口中,每一个 ServiceMethod
都对应了一个接口。
对于 Service
的创建,它是通过动态代理,对每个接口内定义的方法进行了代理,若设置 了validateEagerly
则会在创建 Service 接口对象时进行注解的解析以及 ServiceMethod
的创建,否则会在方法调用时再创建对应的 ServiceMethod
对象,在多次调用的情况下,它通过 serviceMethodCache
对已经解析的 ServiceMethod
进行了缓存从而避免了重复解析带来的性能损耗。
这个对象的创建首先会经过 RequestFactory.parseAnnotations
对方法中的注解进行解析:
对于方法的请求方式注解,它会通过 parseHttpMethodAndPath
方法获取注解对应的请求方式以及注解中的 url 等信息并保存起来,在创建请求的时候设置进 RequestBuilder
。
对于方法的 Headers 注解,它会将 Header 注解解析为 Headers 对象并保存起来,在创建请求的时候设置进 RequestBuilder
。
对于方法的参数,它会将每个参数根据具体的注解(@Query 等)解析为对应的 ParamterHandler
,在创建请求的时候,会通过它的 apply 方法将参数提交到 RequestBuilder
中。
之后,这个对象会通过 HttpServiceMethod.parseAnnotations
对 ServiceMethod
对象进行创建,它在创建的过程中同时进行了接口对应的 CallAdapter
以及 Converter
的创建。
其中,CallAdapter
用于将Call
对象适配为需要的类型 T 对象,也就是对 Call 进行转换。
而 Converter
则是用于将 F 类型的数据转换为 T,往往是用于对 Response
的 body 进行转换。
对于 CallAdapter
和 Converter
都是通过它们对应的工厂类进行创建,创建时会根据工厂列表的顺序从前向后尝试进行创建,也就是说在工厂列表中越靠前的工厂其优先级越大。
同时,Retrofit
还引入了对 Continuation
协程的支持,它会将 ServerMethod
最终包装为一个 suspend
方法从而对协程进行支持。
Retrofit
的网络请求的执行依赖于 OkHttp
,它首先会通过 RequestFactory
进行 Request 的构造,它的参数通过前面解析的信息得来。之后会将这个 Request 包装为一个 okhttp3.Call
,在同步和异步请求时分别调用其对应的 execute 及 enqueue
方法。同时,为了避免okhttp3.Call
的重复创建,它对之前创建的 okhttp3.Call
进行了复用。
链接
参考资料:
GitHub
带你一步步剖析Retrofit 源码解析