知识点:
代理模式、反射
1:用法:
public interface TestApi { @GET("search") Observable<List<TestImage>> search(@Query("q") String query); }
public interface TestApi { @GET("search") Observable<List<TestImage>> search(@Query("q") String query); }
private static OkHttpClient okHttpClient = new OkHttpClient(); private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create(); private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJava2CallAdapterFactory.create(); public static TestApi getTestApi() { if (testApi == null) { Retrofit retrofit = new Retrofit.Builder() .client(okHttpClient) .baseUrl("http://www.zhuangbi.info/") .addConverterFactory(gsonConverterFactory) .addCallAdapterFactory(rxJavaCallAdapterFactory) .build(); testApi = retrofit.create(TestApi.class); } return testApi; }
getTestApi().search("test")。。。。
.subscribe(items->{
......
);
2:总体流程:
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(); @Override public 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); } ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall); } }); }
以上这段代码用到了动态代理模式,所谓动态代理模式,就是只要知道了一个类的字节码文件.class,就能得到该类的方法和属性。
通常代理模式有一个被委托类,代理类以及一个interface,代理类持有被委托类,被委托类被调用的所有方法都将转换为invoke执行。
该代码中interface有了,代理类也有了,但是代理类并没有去持有被委托类,而是利用代理模式的这种特性去执行其他操作:
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall);
先看loadServiceMethod(method):
ServiceMethod<?, ?> loadServiceMethod(Method method) { 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; }
最重要的是:result = new ServiceMethod.Builder<>(this, method).build();
这里返回一个Servicemethod的类:
public ServiceMethod build() { callAdapter = createCallAdapter(); responseType = callAdapter.responseType(); if (responseType == Response.class || responseType == okhttp3.Response.class) { throw methodError("'" + Utils.getRawType(responseType).getName() + "' is not a valid response body type. Did you mean ResponseBody?"); } responseConverter = createResponseConverter(); for (Annotation annotation : methodAnnotations) { parseMethodAnnotation(annotation); } if (httpMethod == null) { throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.)."); } if (!hasBody) { if (isMultipart) { throw methodError( "Multipart can only be specified on HTTP methods with request body (e.g., @POST)."); } if (isFormEncoded) { throw methodError("FormUrlEncoded can only be specified on HTTP methods with " + "request body (e.g., @POST)."); } } int parameterCount = parameterAnnotationsArray.length; parameterHandlers = new ParameterHandler<?>[parameterCount]; for (int p = 0; p < parameterCount; p++) { Type parameterType = parameterTypes[p]; if (Utils.hasUnresolvableType(parameterType)) { throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s", parameterType); } Annotation[] parameterAnnotations = parameterAnnotationsArray[p]; if (parameterAnnotations == null) { throw parameterError(p, "No Retrofit annotation found."); } parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations); } if (relativeUrl == null && !gotUrl) { throw methodError("Missing either @%s URL or @Url parameter.", httpMethod); } if (!isFormEncoded && !isMultipart && !hasBody && gotBody) { throw methodError("Non-body HTTP method cannot contain @Body."); } if (isFormEncoded && !gotField) { throw methodError("Form-encoded method must contain at least one @Field."); } if (isMultipart && !gotPart) { throw methodError("Multipart method must contain at least one @Part."); } return new ServiceMethod<>(this); }
以上这段代码主要有两个作用:
1:得到callAdapter供给前面的 return serviceMethod.callAdapter.adapt(okHttpCall);使用
callAdapter = createCallAdapter();
private CallAdapter<T, R> createCallAdapter() { 。。。。。。。。。。 Annotation[] annotations = method.getAnnotations(); try { //noinspection unchecked return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations); 。。。。。。。。。 }
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) { return nextCallAdapter(null, returnType, annotations); }
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { 。。。。。。。。。。。。。int start = adapterFactories.indexOf(skipPast) + 1; for (int i = start, count = adapterFactories.size(); i < count; i++) { CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this); if (adapter != null) { return adapter; } } 。。。。。。。。。 }
serviceMethod.callAdapter.adapt(okHttpCall);可以看到这里所需的callAdapter在这个地方拿到:
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
adapterFactories是属于Retrofit类的,通过查找可以知道是通过
public Builder addCallAdapterFactory(CallAdapter.Factory factory) { adapterFactories.add(checkNotNull(factory, "factory == null")); return this; }
添加进来的,而这个正式应用层添加的:
Retrofit retrofit = new Retrofit.Builder() .client(okHttpClient) .baseUrl("http://www.zhuangbi.info/") .addConverterFactory(gsonConverterFactory) .addCallAdapterFactory(rxJavaCallAdapterFactory) .build();
所以我们找到了:RxJava2CallAdapterFactory
前面我们分析到:CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
所以serviceMethod.callAdapter.adapt(okHttpCall);这里的adapter是:
RxJava2CallAdapterFactory的get方法得到:
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { Class<?> rawType = getRawType(returnType); 。。。。。。。return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false); }
所以最终锁定到:
RxJava2CallAdapter:
然后执行adapt:
public Object adapt(Call<R> call) { Observable<Response<R>> responseObservable = isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call); Observable<?> observable; if (isResult) { observable = new ResultObservable<>(responseObservable); } else if (isBody) { observable = new BodyObservable<>(responseObservable); } else { observable = responseObservable; } if (scheduler != null) { observable = observable.subscribeOn(scheduler); } if (isFlowable) { return observable.toFlowable(BackpressureStrategy.LATEST); } if (isSingle) { return observable.singleOrError(); } if (isMaybe) { return observable.singleElement(); } if (isCompletable) { return observable.ignoreElements(); } return observable; }
以上过程中:
Rxjava2CallAdapter持有OkHttpCall, OKHttpCall持有method,method持有Retrofit的各种信息,继续往下走:
看Rxjava2CallAdapter的adapt:
public Object adapt(Call<R> call) { Observable<Response<R>> responseObservable = isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call); Observable<?> observable; if (isResult) { observable = new ResultObservable<>(responseObservable); } else if (isBody) { observable = new BodyObservable<>(responseObservable); } else { observable = responseObservable; }
。。。。。。。。。。
return observable; }
这里生成了CallEnqueueObservable,并持有OkHttpCall,这时候回到最开始的地方:
getZhuangbiApi().search("装逼")。。。。 .subscribe(items->{ ...... );
这里的getZhuangbiApi()就是CallEnqueueObservable,我们代码跟进subcribe:
public final void subscribe(Observer<? super T> observer) { ObjectHelper.requireNonNull(observer, "observer is null"); try { observer = RxJavaPlugins.onSubscribe(this, observer); ObjectHelper.requireNonNull(observer, "Plugin returned null Observer"); subscribeActual(observer); 。。。。。。。 } }
会发现这里有个subscribeActual,我们就知道这里执行的是CallEnqueueObservable的subscribeActual:
protected void subscribeActual(Observer<? super Response<T>> observer) { // Since Call is a one-shot type, clone it for each new observer. Call<T> call = originalCall.clone(); CallCallback<T> callback = new CallCallback<>(call, observer); observer.onSubscribe(callback); call.enqueue(callback); }
绕了一圈,又回到了OkhttpCall这个类,执行enqueue:
public void enqueue(final Callback<T> callback) { checkNotNull(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) { 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) throws IOException { Response<T> response; try { response = parseResponse(rawResponse); } catch (Throwable e) { callFailure(e); return; } callSuccess(response); } @Override public void onFailure(okhttp3.Call call, IOException e) { try { callback.onFailure(OkHttpCall.this, e); } catch (Throwable t) { t.printStackTrace(); } } private void callFailure(Throwable e) { try { callback.onFailure(OkHttpCall.this, e); } catch (Throwable t) { t.printStackTrace(); } } private void callSuccess(Response<T> response) { try { callback.onResponse(OkHttpCall.this, response); } catch (Throwable t) { t.printStackTrace(); } } }); }
3:动态代理
前面说到动态代理,我们传进来的是一个interface,如何产生一个代理类呢:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { Objects.requireNonNull(h); final Class<?>[] intfs = interfaces.clone(); 。。。。。 Class<?> cl = getProxyClass0(loader, intfs); 。。。。。。。。。。。 final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { // Android-changed: Removed AccessController.doPrivileged cons.setAccessible(true); } return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { 。。。。。。。。。。。。。 }
这个主要看的一个方法是:
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } // If the proxy class defined by the given loader implementing // the given interfaces exists, this will simply return the cached copy; // otherwise, it will create the proxy class via the ProxyClassFactory return proxyClassCache.get(loader, interfaces); }
可以看到Class是由proxyClassCache的get得到的,再去找proxyClassCache:
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
这里我们找到:ProxyClassFactory:
private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> { 。。。。。。。。。。。。。
。。。。。。。。。。。。。。。
/* * Choose a name for the proxy class to generate. */ long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num; return generateProxy(proxyName, interfaces, loader, methodsArray, exceptionsArray); } } }
最主要的是最后几行代码:
long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num; return generateProxy(proxyName, interfaces, loader, methodsArray, exceptionsArray);
generateProxy是一个native的方法,所以代理类的字节码最终是由这里产生的。
该字节码的名字格式为:proxyPkg + proxyClassNamePrefix + num,
即:包名+$Proxy+num
然后通过newProxyInstance方法里面的:
return cons.newInstance(new Object[]{h});
生成动态代理类返回。