必备知识 - 注解反射与动态代理(Retrofit)
通过分析Retrofit的源码可以来梳理注解的进阶使用
1. Retrofit介绍
- Retrofit 是一种用于在 Android 应用程序中进行网络请求的开源库
- 内部封装了OKhttp,简化了网络请求的过程,并提供简易API
- Retrofit使用了注解+反射+动态代理,让我像调用函数一样执行网路请求
- 这个库大家都用的很熟了,无需多言,直接开始
2. API定义以及使用
public void initRetrofit(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService apiService = retrofit.create(ApiService.class);
Call<String> testCall = apiService.listRepos("test");
testCall.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
}
3.retrofit构建流程
public Builder() {
this(Platform.get());
}
private static Platform findPlatform() {
return "Dalvik".equals(System.getProperty("java.vm.name"))
? new Platform.Android()
: new Platform(true);
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
....
this.baseUrl = baseUrl;
return this;
}
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
...
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
4.反射收集请求信息,并封装
public <T> T create(final Class<T> service) {
return (T)
Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] {service}, new InvocationHandler() {
private final Platform platform = Platform.get();
@Override
public @Nullable
Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
public 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;
}
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
}
.....
}
@Override void apply(RequestBuilder builder, @Nullable T value) throws IOException {
if (value == null) return;
String queryValue = valueConverter.convert(value);
if (queryValue == null) return;
builder.addQueryParam(name, queryValue, encoded);
}
void addQueryParam(String name, @Nullable String value, boolean encoded) {
urlBuilder = baseUrl.newBuilder(relativeUrl);
....
urlBuilder.addEncodedQueryParameter(name, value);
}
RequestFactory(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;
isKotlinSuspendFunction = builder.isKotlinSuspendFunction;
}
5.发起请求,处理响应
- okhttp请求流程
- 创建OkhttpClient
- 封装Request
- 调用dispatcher(内部使用线程池做请求分发)
- 使用拦截器来处理网路请求流程 (各个拦截器职责单一、使用责任链,层层下发)
- response回调处理、格式转换、线程切换
@Override
public void enqueue(okhttp3.Callback responseCallback) {
synchronized (this) {
client.dispatcher().enqueue(new RealCall.AsyncCall(responseCallback));
}
}
synchronized void enqueue(RealCall.AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
okhttp3.Response getResponseWithInterceptorChain() throws IOException {
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
@Override
public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
callback.onFailure(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, t);
}
});
}
});
}
6.总结
- 代理就是让三方帮我们做事情,我们不需要关心过程,只注重结果就行了,这种方式能做到单一职责,互不干扰
- 静态代理:只能1对1,扩展性差,但是可读性强
- 动态代理:可以1对多,扩展性强
- 基本注解的使用告一段落了,后面对JVM虚拟机做一个学习记录。