Retrofit 源码 part 1 Retrofit 大致上就是动态代理+注释处理
简单来说 如果我们要进行一个像这样的网络请求
1 2 3 GitHubService service = retrofit.create(GitHubService.class ) ; Call<List<Repo>> repos = service.listRepos("octocat" );
摘自retrofit
其内部的过程是这样的
下面看看具体内容.
create() Retrofit 的源码我们从Retrofit.create这个方法开始看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 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); } }); }
在craete()中,先对参数final Class service做一个校验,是否是一个interface,是否有继承自其他interface之类的。
这一部分的核心是返回了一个 Proxy.newProxyInstance(...)
, 使用Java 动态代理。同时动态代理的 InvocationHandler 的 invoke()方法的实现与service的注释相关.
我们看到这一部分
1 return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
loadServiceMethod 每次执行代理的方法的时候,执行loadServiceMethod.invoke, 所以就是说 Retrofit.create()返回的结果由动态代理帮助实现。那么怎么样把service的方法调用之后就实现网络请求呢?这就由注释实现了。 loadserviceMethod的相关代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 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 resuslt = ServiceMethod.parseAnnotations(this , method);
parseAnnotations 很明显这个是对注释进行处理,那么我们需要关注parseAnnotations()做了怎么样的处理.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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 T invoke (Object[] args) ; }
ServiceMethod的源码很短,简单看来, ServiceMethod.parseAnnotations(…) 完成了两件事
从 retrofit, method 中取得了RequestFactory类的示例retrofitFactory
将 retrofitFactory作为参数交由 HttpServiceMethod处理.
RequestFactory.parseAnnotations(retrofit, method) 这里是真正的对parseAnnotation 进行处理,为什么这么说呢,read the fucking code.
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 73 74 75 76 77 78 79 80 81 final class RequestFactory { static RequestFactory parseAnnotations (Retrofit retrofit, Method method) { return new Builder(retrofit, method).build(); } RequestFactory(Builder builder) { method = builder.method; baseUrl = builder.retrofit.baseUrl; httpMethod = builder.httpMethod; relativeUrl = builder.relativeUrl; headers = builder.headers; contentType = builder.contentType; hasBody = builder.hasBody; isFormEncoded = builder.isFormEncoded; isMultipart = builder.isMultipart; parameterHandlers = builder.parameterHandlers; } ... static final class Builder { ... 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); } ... return new RequestFactory(this ); } 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 再 HttpServiceMethod.parseAnnotations中 再次将retrofit ,method进行处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 final class HttpServiceMethod <ResponseT , ReturnT > extends ServiceMethod <ReturnT > { static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations ( Retrofit retrofit, Method method, RequestFactory requestFactory) { CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method); ... Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType); okhttp3.Call.Factory callFactory = retrofit.callFactory; return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter); } ... }
从这里开始 retrofit 和method转化为 requestFactory callFactory callAdapter responseConverter作为参数构建 HttpServiceMethod实例。 所以我们需要去查看HttpServiceMethod是来干什么的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 final class HttpServiceMethod <ResponseT , ReturnT > extends ServiceMethod <ReturnT > { private HttpServiceMethod (RequestFactory requestFactory, okhttp3.Call.Factory callFactory, CallAdapter<ResponseT, ReturnT> callAdapter, Converter<ResponseBody, ResponseT> responseConverter) { this .requestFactory = requestFactory; this .callFactory = callFactory; this .callAdapter = callAdapter; this .responseConverter = responseConverter; } @Override ReturnT invoke (Object[] args) { return callAdapter.adapt( new OkHttpCall<>(requestFactory, args, callFactory, responseConverter)); } ... }
可以看出,当 service里面的方法被执行的时候,是由callAdapter.adapt()处理一个OkHttoCall完成的。 到此为止,retrofit与okhttp之间的联系也就找到了.
我对动态代理也不熟悉,暂时到此为止,。