定制目的
我们的最终目的是将中间层拿掉,直接集成okhttp的包装框架,JLRetrofit的存在其实就是来兼容我们老的逻辑,让各端能平滑过渡,慢慢迁移。
博客内容
1.了解Retrofit背后的知识,深入理解
2.分析Mini版Retrofit框架代码,来看看如何实现一个简单的Retrofit
理解Retrofit
下面详细了解下四个知识点,懂了之后你就会发现,retrofit真的很简单。
最核心的四个知识点:
注解
动态代理
反射
设计模式
注解
注解原理点我或者直接看下图

动态代理
原理请看点我
反射
原理请看点我
设计模式
整个流程中运用的设计模式如下

分析Mini版Retrofit框架代码
我们分析的流程如下:
分析POST注解->如何解析出POST注解内容->根据解析的数据发送POST请求
POST注解
@Documented //注释放到javaDoc中
@Target(METHOD) //注释目标是方法
@Retention(RUNTIME) // 运行时保留
public @interface POST {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* <p>
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
如何解析出POST注解内容
通过搜索查到这,这里判断了注解Annotation 是否是POST类型,是就解析POST类型需要的其他字段
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof POST) {
this.parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
}
}
往上层继续找,RequestFactory build函数里,对一个变量methodAnnotions遍历解析,再找一下this.methodAnnotations哪里来的
RequestFactory build() {
Annotation[] var1 = this.methodAnnotations;
int p = var1.length;
int lastParameter;
for (lastParameter = 0; lastParameter < p; ++lastParameter) {
Annotation annotation = var1[lastParameter];
this.parseMethodAnnotation(annotation);
}
同样还在RequestFactory类中,通过Method类method.getAnnotations()获取的。
Builder(JLRetrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
继续往上找,静态函数,parseAnnotations传递过来。
static RequestFactory parseAnnotations(JLRetrofit retrofit, Method method) {
return (new RequestFactory.Builder(retrofit, method)).build();
}
继续,ServiceMethod抽象类,parseAnnotations函数中调用
static <T> ServiceMethod<T> parseAnnotations(JLRetrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (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);
}
继续,在Retrofit类中 函数loadServiceMethod中调用。
private 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;
}
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() {
private final Object[] emptyArgs = new Object[0];
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
最终看到了create函数,这个函数就是我们在创建api的过程中经常用到的函数。
Call<String> call = new JLRetrofit.Builder().baseUrl("http://").build().create(ServiceApi.class).getBaidu();
try {
call.execute();
} catch (IOException e) {
e.printStackTrace();
}
根据解析的数据发送POST请求
一个网络最终调用execute接口发送请求的,肯定有实现类,要不然如何请求的呢。option+command+B 看图

这里发现两个,最终发送网络请求的其实是OkhttpCall,这里实现了Okhttp的调用。看图,call是okhttp3包下的类

为什么有两个呢?这里用到一个设计模式,装饰者模式,跟我们RecylerView 的adapter一个概念,我们可以添加更多的Adapter来处理数据。
看类名ExecutorCallbackCall可以猜到,这是一个线程管理装饰者,负责异步处理的。
网络请求的参数哪里来的呢,其实所有的参数和注解的内容已经解析出来存在RequestFactory中。
OkHttpCall(RequestFactory requestFactory, Object[] args) {
this.requestFactory = requestFactory;
this.args = args;
}
如图:url、body、httpMethod都会在这个类里解析出来。

整个流程分析完了,准备的比较仓促,不全面,抱歉啊,接下来直接看源码吧。
总结
一个Retrofit框架,整体设计结构蕴藏着很多设计模式,很多良好的代码书写习惯。多分析,多看看,还是有很多收获的。分享就到这,有问题请留言。
网友评论