动态代理:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
调用一个接口的方法时,调用InvocationHandler的invoke(Object proxy, Method method, Object[] args)方法
Retrofit 主要的实现原理是动态代理,它的实现步骤主要有:
1.ServiceMethod解析接口方法上的注解,生成Okhttp.Request需要的参数;
2.生成OkHttpCall,作为okhttp3.Call的代理类;
3.CallAdapter把OkHttpCalll转换为Observable,生成responseObservable;
4.当responseObservable调用subscribe(observer)方法时 ,会调用OkHttpCall的方法,比如enqueue
5,OkHttpCall.enqueue的方法会调用ServiceMethod.toCall方法生成okhttp3.Call
6,用Okhttp请求网络,把请求结果放进observer返回去
public <T> T create(final Class<T> service) {
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
1.ServiceMethod
因为ServiceMethod的主要功能是根据反射解析注解,比较消耗性能,所以会把ServiceMethod缓存,一个method对应一个ServiceMethod
ServiceMethod<?, ?> loadServiceMethod(Method method) {
//先从缓存中寻找ServiceMethod
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//没有就生成,并放入缓存
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
// 把返回值解析成Object
responseConverter = createResponseConverter();
//解析方法的注解,比如get,pot,header
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//解析方法参数注解,比如path
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
return new ServiceMethod<>(this);
}
2.OkHttpCall 和okHttp3.Call有相同的方法,比如调用OkHttpCall的enqueue方法最终执行的okhttp3.Call的enqueue方法,
okhttp3.Call对象是通过serviceMethod.toCall(args)方法创建,toCall方法会跟使用Okhttp创建call一样,先根据serviceMethod解析注解得到的参数生成Request,然后newCall。
3.CallAdapter的adapt方法,把OkHttpCall变成Observable返回,具体做法是生成一个持有OkHttpCall引用的Observable对象。
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
会根据Observable<T> T的类型判断生成哪个Observable
if (isResult) { //Observable<Result>
observable = new ResultObservable<>(responseObservable);
} else if (isBody) { //Observable<R>
observable = new BodyObservable<>(responseObservable);
} else { Observable<Response>
observable = responseObservable;
}